[spatialite] 02/11: Imported Upstream version 4.2.1~rc0

Bas Couwenberg sebastic at xs4all.nl
Sun Oct 26 21:48:10 UTC 2014


This is an automated email from the git hooks/post-receive script.

sebastic-guest pushed a commit to branch experimental
in repository spatialite.

commit 93bce9dc89a7f0c300a5a7c002a407026a58d683
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Oct 26 16:28:49 2014 +0100

    Imported Upstream version 4.2.1~rc0
---
 configure                                          |   23 +-
 configure.ac                                       |    3 +-
 examples/demo1.c                                   |    2 +-
 examples/demo2.c                                   |    2 +-
 examples/demo3.c                                   |    2 +-
 examples/demo4.c                                   |    2 +-
 examples/demo5.c                                   |    2 +-
 spatialite-sql-latest.html                         |  362 +-
 src/Makefile.am                                    |   18 +-
 src/Makefile.in                                    |   28 +-
 src/dxf/dxf_load_distinct.c                        |    9 +
 src/dxf/dxf_load_mixed.c                           |    9 +
 src/dxf/dxf_loader.c                               |    9 +
 src/dxf/dxf_parser.c                               |    9 +
 src/dxf/dxf_private.h                              |    9 +
 src/dxf/dxf_writer.c                               |    9 +
 src/gaiaexif/gaia_exif.c                           |   33 +
 src/gaiageo/gg_advanced.c                          |   24 +-
 src/gaiageo/gg_geometries.c                        |   20 +-
 src/gaiageo/gg_geoscvt.c                           |    8 +-
 src/gaiageo/gg_gml.c                               |   16 +-
 src/gaiageo/gg_kml.c                               |   10 +-
 src/gaiageo/gg_lwgeom.c                            |   24 +-
 src/gaiageo/gg_relations_ext.c                     |   16 +-
 src/gaiageo/gg_shape.c                             |  112 +-
 src/gaiageo/gg_transform.c                         |    8 +-
 src/gaiageo/gg_voronoj.c                           |    2 +-
 src/gaiageo/gg_wkt.c                               |   40 +-
 src/gaiageo/gg_xml.c                               |   10 +-
 src/geopackage/gaia_cvt_gpkg.c                     |    6 +-
 src/headers/spatialite.h                           |  185 +-
 src/headers/spatialite/gaiaexif.h                  |    8 +-
 src/headers/spatialite/gg_formats.h                |   49 +
 src/headers/spatialite/spatialite.h                |    1 +
 src/headers/spatialite/sqlite.h                    |    5 +
 src/headers/spatialite_private.h                   |   16 +
 src/shapefiles/shapefiles.c                        |  175 +-
 src/spatialite/Makefile.am                         |    4 +-
 src/spatialite/Makefile.in                         |   55 +-
 src/spatialite/extra_tables.c                      |  105 +-
 src/spatialite/metatables.c                        |  288 +-
 src/spatialite/spatialite.c                        | 6186 ++++++++++++++------
 src/spatialite/statistics.c                        |    8 +-
 src/spatialite/table_cloner.c                      | 2318 ++++++++
 src/spatialite/virtualbbox.c                       |    9 +-
 src/spatialite/virtualdbf.c                        |   20 +-
 src/spatialite/virtualelementary.c                 | 1063 ++++
 src/spatialite/virtualfdo.c                        |    2 +-
 src/spatialite/virtualshape.c                      |   20 +-
 test/Makefile.am                                   |    7 +-
 test/Makefile.in                                   |   98 +-
 test/check_bufovflw.c                              |   26 +-
 test/check_clone_table.c                           | 1442 +++++
 test/check_dxf.c                                   |   24 +-
 test/check_spatialindex.c                          |   10 +
 test/check_sql_stmt.c                              |   17 +-
 test/check_virtualelem.c                           | 1134 ++++
 test/check_virtualtable3.c                         |    2 +-
 test/check_virtualtable6.c                         |    2 +-
 test/sql_stmt_freexl_tests/Makefile.am             |    8 +
 .../Makefile.in                                    |   27 +-
 test/sql_stmt_freexl_tests/loadxls1.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls2.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls3.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls4.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls5.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls6.testcase       |    7 +
 test/sql_stmt_freexl_tests/loadxls7.testcase       |    7 +
 test/sql_stmt_security_tests/Makefile.am           |   93 +
 test/sql_stmt_security_tests/Makefile.in           |   93 +
 test/sql_stmt_security_tests/exportdbf1.testcase   |    7 +
 test/sql_stmt_security_tests/exportdbf2.testcase   |    7 +
 test/sql_stmt_security_tests/exportdbf3.testcase   |    7 +
 test/sql_stmt_security_tests/exportdbf4.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf1.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf10.testcase  |    7 +
 test/sql_stmt_security_tests/exportdxf11.testcase  |    7 +
 test/sql_stmt_security_tests/exportdxf2.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf3.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf4.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf5.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf6.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf7.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf8.testcase   |    7 +
 test/sql_stmt_security_tests/exportdxf9.testcase   |    7 +
 .../exportgeojson1.testcase                        |    7 +
 .../exportgeojson10.testcase                       |    7 +
 .../exportgeojson11.testcase                       |    7 +
 .../exportgeojson2.testcase                        |    7 +
 .../exportgeojson3.testcase                        |    7 +
 .../exportgeojson4.testcase                        |    7 +
 .../exportgeojson5.testcase                        |    7 +
 .../exportgeojson6.testcase                        |    7 +
 .../exportgeojson7.testcase                        |    7 +
 .../exportgeojson8.testcase                        |    7 +
 .../exportgeojson9.testcase                        |    7 +
 test/sql_stmt_security_tests/exportkml1.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml2.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml3.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml4.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml5.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml6.testcase   |    7 +
 test/sql_stmt_security_tests/exportkml7.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp1.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp2.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp3.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp4.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp5.testcase   |    7 +
 test/sql_stmt_security_tests/exportshp6.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf1.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf2.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf3.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf4.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf5.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf6.testcase   |    7 +
 test/sql_stmt_security_tests/importdbf7.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf1.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf10.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf11.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf12.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf13.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf14.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf15.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf16.testcase  |    7 +
 test/sql_stmt_security_tests/importdxf2.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf3.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf4.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf5.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf6.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf7.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf8.testcase   |    7 +
 test/sql_stmt_security_tests/importdxf9.testcase   |    7 +
 .../sql_stmt_security_tests/importdxfdir1.testcase |    7 +
 .../importdxfdir10.testcase                        |    7 +
 .../importdxfdir11.testcase                        |    7 +
 .../importdxfdir12.testcase                        |    7 +
 .../importdxfdir13.testcase                        |    7 +
 .../importdxfdir14.testcase                        |    7 +
 .../importdxfdir15.testcase                        |    7 +
 .../importdxfdir16.testcase                        |    7 +
 .../sql_stmt_security_tests/importdxfdir2.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir3.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir4.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir5.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir6.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir7.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir8.testcase |    7 +
 .../sql_stmt_security_tests/importdxfdir9.testcase |    7 +
 test/sql_stmt_security_tests/importshp1.testcase   |    7 +
 test/sql_stmt_security_tests/importshp10.testcase  |    7 +
 test/sql_stmt_security_tests/importshp11.testcase  |    7 +
 test/sql_stmt_security_tests/importshp12.testcase  |    7 +
 test/sql_stmt_security_tests/importshp13.testcase  |    7 +
 test/sql_stmt_security_tests/importshp14.testcase  |    7 +
 test/sql_stmt_security_tests/importshp2.testcase   |    7 +
 test/sql_stmt_security_tests/importshp3.testcase   |    7 +
 test/sql_stmt_security_tests/importshp4.testcase   |    7 +
 test/sql_stmt_security_tests/importshp5.testcase   |    7 +
 test/sql_stmt_security_tests/importshp6.testcase   |    7 +
 test/sql_stmt_security_tests/importshp7.testcase   |    7 +
 test/sql_stmt_security_tests/importshp8.testcase   |    7 +
 test/sql_stmt_security_tests/importshp9.testcase   |    7 +
 test/sql_stmt_tests/Makefile.am                    |   62 +
 test/sql_stmt_tests/Makefile.in                    |   62 +
 test/sql_stmt_tests/checkdupl1.testcase            |    7 +
 test/sql_stmt_tests/checkdupl2.testcase            |    7 +
 test/sql_stmt_tests/clonetable1.testcase           |    7 +
 test/sql_stmt_tests/clonetable10.testcase          |    7 +
 test/sql_stmt_tests/clonetable11.testcase          |    7 +
 test/sql_stmt_tests/clonetable12.testcase          |    7 +
 test/sql_stmt_tests/clonetable13.testcase          |    7 +
 test/sql_stmt_tests/clonetable14.testcase          |    7 +
 test/sql_stmt_tests/clonetable15.testcase          |    7 +
 test/sql_stmt_tests/clonetable2.testcase           |    7 +
 test/sql_stmt_tests/clonetable3.testcase           |    7 +
 test/sql_stmt_tests/clonetable4.testcase           |    7 +
 test/sql_stmt_tests/clonetable5.testcase           |    7 +
 test/sql_stmt_tests/clonetable6.testcase           |    7 +
 test/sql_stmt_tests/clonetable7.testcase           |    7 +
 test/sql_stmt_tests/clonetable8.testcase           |    7 +
 test/sql_stmt_tests/clonetable9.testcase           |    7 +
 test/sql_stmt_tests/dropgeo1.testcase              |    7 +
 test/sql_stmt_tests/dropgeo2.testcase              |    7 +
 test/sql_stmt_tests/dropgeo3.testcase              |    7 +
 test/sql_stmt_tests/dropgeo4.testcase              |    7 +
 test/sql_stmt_tests/dropgeo5.testcase              |    7 +
 test/sql_stmt_tests/elemgeo1.testcase              |    7 +
 test/sql_stmt_tests/elemgeo2.testcase              |    7 +
 test/sql_stmt_tests/elemgeo3.testcase              |    7 +
 test/sql_stmt_tests/elemgeo4.testcase              |    7 +
 test/sql_stmt_tests/elemgeo5.testcase              |    7 +
 test/sql_stmt_tests/elemgeo6.testcase              |    7 +
 test/sql_stmt_tests/removedupl1.testcase           |    7 +
 test/sql_stmt_tests/removedupl2.testcase           |    7 +
 test/sql_stmt_tests/setendpoint1.testcase          |    7 +
 test/sql_stmt_tests/setendpoint10.testcase         |    7 +
 test/sql_stmt_tests/setendpoint11.testcase         |    7 +
 test/sql_stmt_tests/setendpoint12.testcase         |    7 +
 test/sql_stmt_tests/setendpoint13.testcase         |    7 +
 test/sql_stmt_tests/setendpoint14.testcase         |    7 +
 test/sql_stmt_tests/setendpoint15.testcase         |    7 +
 test/sql_stmt_tests/setendpoint16.testcase         |    7 +
 test/sql_stmt_tests/setendpoint2.testcase          |    7 +
 test/sql_stmt_tests/setendpoint3.testcase          |    7 +
 test/sql_stmt_tests/setendpoint4.testcase          |    7 +
 test/sql_stmt_tests/setendpoint5.testcase          |    7 +
 test/sql_stmt_tests/setendpoint6.testcase          |    7 +
 test/sql_stmt_tests/setendpoint7.testcase          |    7 +
 test/sql_stmt_tests/setendpoint8.testcase          |    7 +
 test/sql_stmt_tests/setendpoint9.testcase          |    7 +
 test/sql_stmt_tests/setstartpoint1.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint10.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint11.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint12.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint13.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint14.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint15.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint16.testcase       |    7 +
 test/sql_stmt_tests/setstartpoint2.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint3.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint4.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint5.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint6.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint7.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint8.testcase        |    7 +
 test/sql_stmt_tests/setstartpoint9.testcase        |    7 +
 test/sql_stmt_xmlsec_tests/Makefile.am             |   11 +-
 test/sql_stmt_xmlsec_tests/Makefile.in             |   11 +-
 test/sql_stmt_xmlsec_tests/importwfs1.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs2.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs3.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs4.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs5.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs6.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs7.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs8.testcase     |    7 +
 test/sql_stmt_xmlsec_tests/importwfs9.testcase     |    7 +
 237 files changed, 13418 insertions(+), 2245 deletions(-)

diff --git a/configure b/configure
index b8cdd25..bd40735 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libspatialite 4.2.0.
+# Generated by GNU Autoconf 2.69 for libspatialite 4.2.1-rc0.
 #
 # Report bugs to <a.furieri at lqt.it>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libspatialite'
 PACKAGE_TARNAME='libspatialite'
-PACKAGE_VERSION='4.2.0'
-PACKAGE_STRING='libspatialite 4.2.0'
+PACKAGE_VERSION='4.2.1-rc0'
+PACKAGE_STRING='libspatialite 4.2.1-rc0'
 PACKAGE_BUGREPORT='a.furieri at lqt.it'
 PACKAGE_URL=''
 
@@ -1362,7 +1362,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libspatialite 4.2.0 to adapt to many kinds of systems.
+\`configure' configures libspatialite 4.2.1-rc0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1432,7 +1432,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libspatialite 4.2.0:";;
+     short | recursive ) echo "Configuration of libspatialite 4.2.1-rc0:";;
    esac
   cat <<\_ACEOF
 
@@ -1566,7 +1566,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libspatialite configure 4.2.0
+libspatialite configure 4.2.1-rc0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2110,7 +2110,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libspatialite $as_me 4.2.0, which was
+It was created by libspatialite $as_me 4.2.1-rc0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2981,7 +2981,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libspatialite'
- VERSION='4.2.0'
+ VERSION='4.2.1-rc0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -17190,7 +17190,7 @@ else
 fi
 
 
-ac_config_files="$ac_config_files Makefile src/Makefile src/headers/Makefile src/gaiaaux/Makefile src/gaiaexif/Makefile src/gaiageo/Makefile src/gaiageo/flex/Makefile src/gaiageo/lemon/Makefile src/gaiageo/lemon/lemon_src/Makefile src/geopackage/Makefile src/spatialite/Makefile src/shapefiles/Makefile src/dxf/Makefile src/md5/Makefile src/srsinit/Makefile src/srsinit/epsg_update/Makefile src/connection_cache/Makefile src/connection_cache/generator/Makefile src/virtualtext/Makefile src/wf [...]
+ac_config_files="$ac_config_files Makefile src/Makefile src/headers/Makefile src/gaiaaux/Makefile src/gaiaexif/Makefile src/gaiageo/Makefile src/gaiageo/flex/Makefile src/gaiageo/lemon/Makefile src/gaiageo/lemon/lemon_src/Makefile src/geopackage/Makefile src/spatialite/Makefile src/shapefiles/Makefile src/dxf/Makefile src/md5/Makefile src/srsinit/Makefile src/srsinit/epsg_update/Makefile src/connection_cache/Makefile src/connection_cache/generator/Makefile src/virtualtext/Makefile src/wf [...]
 
 
 # exporting the TARGET_CPU string
@@ -19000,7 +19000,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libspatialite $as_me 4.2.0, which was
+This file was extended by libspatialite $as_me 4.2.1-rc0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19066,7 +19066,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libspatialite config.status 4.2.0
+libspatialite config.status 4.2.1-rc0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -19608,6 +19608,7 @@ do
     "test/sql_stmt_libxml2_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_libxml2_tests/Makefile" ;;
     "test/sql_stmt_security_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_security_tests/Makefile" ;;
     "test/sql_stmt_xmlsec_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_xmlsec_tests/Makefile" ;;
+    "test/sql_stmt_freexl_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_freexl_tests/Makefile" ;;
     "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
     "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;;
     "spatialite.pc") CONFIG_FILES="$CONFIG_FILES spatialite.pc" ;;
diff --git a/configure.ac b/configure.ac
index a42cac4..21ab175 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT(libspatialite, 4.2.0, a.furieri at lqt.it)
+AC_INIT(libspatialite, 4.2.1-rc0, a.furieri at lqt.it)
 AC_LANG(C)
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -135,6 +135,7 @@ AC_CONFIG_FILES([Makefile \
 		test/sql_stmt_libxml2_tests/Makefile \
 		test/sql_stmt_security_tests/Makefile \
 		test/sql_stmt_xmlsec_tests/Makefile \
+		test/sql_stmt_freexl_tests/Makefile \
 		examples/Makefile \
 		Doxyfile \
 		spatialite.pc])
diff --git a/examples/demo1.c b/examples/demo1.c
index 7e731a2..7b5df71 100644
--- a/examples/demo1.c
+++ b/examples/demo1.c
@@ -2,7 +2,7 @@
 
 demo1.c
 
-Author: Sandro Furieri a-furieri at lqt.it
+Author: Sandro Furieri a.furieri at lqt.it
  
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author be held liable for any
diff --git a/examples/demo2.c b/examples/demo2.c
index ebc6e94..47f3897 100644
--- a/examples/demo2.c
+++ b/examples/demo2.c
@@ -2,7 +2,7 @@
 
 demo2.c
 
-Author: Sandro Furieri a-furieri at lqt.it
+Author: Sandro Furieri a.furieri at lqt.it
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author be held liable for any
diff --git a/examples/demo3.c b/examples/demo3.c
index bc63f45..6690228 100644
--- a/examples/demo3.c
+++ b/examples/demo3.c
@@ -2,7 +2,7 @@
 
 demo3.c
 
-Author: Sandro Furieri a-furieri at lqt.it
+Author: Sandro Furieri a.furieri at lqt.it
  
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author be held liable for any
diff --git a/examples/demo4.c b/examples/demo4.c
index 110137f..758c5e2 100644
--- a/examples/demo4.c
+++ b/examples/demo4.c
@@ -2,7 +2,7 @@
 
 demo4.c
 
-Author: Sandro Furieri a-furieri at lqt.it
+Author: Sandro Furieri a.furieri at lqt.it
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author be held liable for any
diff --git a/examples/demo5.c b/examples/demo5.c
index 85839d5..cc98233 100644
--- a/examples/demo5.c
+++ b/examples/demo5.c
@@ -2,7 +2,7 @@
 
 demo5.c
 
-Author: Sandro Furieri a-furieri at lqt.it
+Author: Sandro Furieri a.furieri at lqt.it
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author be held liable for any
diff --git a/spatialite-sql-latest.html b/spatialite-sql-latest.html
index ca672ba..62605f4 100644
--- a/spatialite-sql-latest.html
+++ b/spatialite-sql-latest.html
@@ -11,7 +11,7 @@
 			i {color:navy;}
 		</style>
 	</head><body bgcolor="#fffff0">
-		<h2>SpatiaLite 4.2.0          SQL functions reference list</h2>
+		<h2>SpatiaLite 4.2.1          SQL functions reference list</h2>
 		<a href="https://www.gaia-gis.it/fossil/libspatialite">back</a>
 		<ul>
 			<li><a href="#version">SQL Version Info [and build options testing] functions</a></li>
@@ -54,6 +54,7 @@
 			<li><a href="#p17">SQL functions for MbrCache-based queries</a></li>
 			<li><a href="#p18">SQL functions for R*Tree-based queries (Geometry Callbacks)</a></li>
 			<li><a href="#xmlBlob">SQL functions supporting XmlBLOB</a></li>
+			<li><a href="#advanced">miscellaneous advanced SQL functions</a></li>
 		</ul>
 		<table bgcolor="#e2eae2" border="1" cellpadding="2" cellspacing="2" width="100%">
 			<tbody><tr><td colspan="5" align="center" bgcolor="#f0e0c0">
@@ -437,10 +438,15 @@
 				<td colspan="3">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and –1 for UNKNOWN
 					corresponding to a function invocation on NULL or not-BLOB argument.<hr>
 					TRUE if this BLOB object corresponds to a valid WebP image</td></tr>
+			<tr><td><b>IsJP2Blob</b></td>
+				<td>IsJP2Blob( image <i>BLOB</i> ) : <i>Integer</i></td>
+				<td colspan="3">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and –1 for UNKNOWN
+					corresponding to a function invocation on NULL or not-BLOB argument.<hr>
+					TRUE if this BLOB object corresponds to a valid JP2 [Jpeg2000] image</td></tr>
 			<tr><td><b>GetMimeType</b></td>
 				<td>GetMimeType( payload <i>BLOB</i> ) : <i>String</i></td>
 				<td colspan="3">The return type is Text, and could be one of: <b>image/gif</b>, <b>image/png</b>,
-					<b>image/jpeg</b>, <b>image/tiff</b>, <b>image/svg+xml</b>, <b>application/xml</b>,
+					<b>image/jpeg</b>, <b>image/jp2</b>, </b></v><b>image/tiff</b>, <b>image/svg+xml</b>, <b>application/xml</b>,
 					<b>application/zip</b>,	<b>application/pdf</b>.<br>
 					NULL could be returned for an invalid argument or if no valid mime-type is detected.</td></tr>
 			<tr><td><b>BlobFromFile</b></td>
@@ -527,7 +533,7 @@
 				<td></td>
 				<td align="center" bgcolor="#d0f0d0">base</td>
 				<td>a Linestring Geometry will be returned connecting all the input Points (accordingly to input sequence); <b>direction=FALSE</b> implies <u>reverse order</u>.<br>
-				<u>Please note</u>: similar to the previuous one, but this one is an ordinary (not aggregate) function; a MultiPoint input is always expected.</b><hr>
+				<u>Please note</u>: similar to the previuous one, but this one is an ordinary (not aggregate) function; a MultiPoint input is always expected.<hr>
 				NULL will be returned if any error is encountered</td></tr>
                         <tr><td><b>MakeCircle</b></td>
 				<td>MakeCircle( cx <i>Double precision</i> , cy <i>Double precision</i> ,
@@ -994,22 +1000,6 @@ a Geometry will be returned representing the MBR for the corresponding GARS area
 				<td></td>
 				<td align="center" bgcolor="#d0f0d0">base</td>
 				<td>construct a geometric object given its FGF binary Representation</td></tr>
-			<tr><td><b>ExportDXF</b></td>
-				<td>ExportDXF( out_dir <i>String</i> , filename <i>String</i> , sql_query <i>String</i> , layer_col_name <i>String</i> , 
-                                geom_col_name <i>String</i> , label_col_name <i>String</i> , text_height_col_name <i>String</i> , 
-                                text_rotation_col_name <i>String</i> , geom_filter <i>Geometry</i> [ , precision <i>Integer</i> ] ) : <i>Integer</i></td>
-				<td colspan="3">Will export a whole DXF file.<ul>
-                                        <li>The output file path is controlled by <b>out_dir</b> and <b>filename</b>.</li>
-					<li><b>sql_query</b> is a complete SQL Statement returning the dataset to be exported.</li>
-					<li><b>layer_col_name</b>, <b>geom_col_name</b>, <b>label_col_name</b>, <b>text_height_col_name</b> 
-					and <b>text_rotation_col_name</b> must specify the corresponding <u>column names</u> within the resultset
-					returned by <b>sql_query</b> (<i>label_col_name</i>, <i>text_height_col_name</i> and <i>text_rotation_col_name</i> could be eventually <b>NULL</b>).</li>
-					<li><b>geom_filter</b> acts as a <u>spatial filter</u> selecting which entities have to be exported (could be <b>NULL</b>).</li>
-					<li>the optional argument <b>precision</b> specificies how many <u>decimal digits</u> are required for coordinate values: if not specified the default is <b>3</b>.</li>
-					</ul>
-					Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success.<hr>
-                                        <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
-                                        Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>	
 			<tr><td colspan="5" align="center" bgcolor="#f0f0c0">
 				<h3><a name="p4">SQL functions on type Geometry</a></h3></td></tr>
 			<tr><th bgcolor="#d0d0d0">Function</th>
@@ -1463,6 +1453,20 @@ algorithm with given <i>tolerance</i> and respecting topology</td></tr>
 				<td align="center" bgcolor="#d0f0d0">base</td>
 				<td>returns a new Linestring by replacing the Point at <b>position</b> (zero-based index).<br>
                                 <b>NULL</b> will be returned if any error is encountered.</td></tr>
+			<tr><td><b>SetStartPoint</b></td>
+				<td>SetStartPoint( line <i>LineString</i> , point <i>Point</i> ) : <i>Linestring</i><hr>
+					ST_SetStartPoint( line <i>LineString</i> , point <i>Point</i> ) : <i>Linestring</i></td>
+				<td></td>
+				<td align="center" bgcolor="#d0f0d0">base</td>
+				<td>returns a new Linestring by replacing its StartPoint.<br>
+                                <b>NULL</b> will be returned if any error is encountered.</td></tr>
+			<tr><td><b>SetEndPoint</b></td>
+				<td>SetEndPoint( line <i>LineString</i> , point <i>Point</i> ) : <i>Linestring</i><hr>
+					ST_SetEndtPoint( line <i>LineString</i> , point <i>Point</i> ) : <i>Linestring</i></td>
+				<td></td>
+				<td align="center" bgcolor="#d0f0d0">base</td>
+				<td>returns a new Linestring by replacing its EndPoint.<br>
+                                <b>NULL</b> will be returned if any error is encountered.</td></tr>
 			<tr><td><b>RemovePoint</b></td>
 				<td>RemovePoint( line <i>LineString</i> , position <i>Integer</i> ) : <i>Linestring</i><hr>
 					ST_RemovePoint( line <i>LineString</i> , position <i>Integer</i> ) : <i>Linestring</i></td>
@@ -2514,6 +2518,22 @@ the return type is Integer, with a return value of 1 for TRUE (success) or 0 for
 				<td align="center" bgcolor="#d0f0d0">base</td>
 				<td>Creates the <b>raster_coverages</b> table required by <b>RasterLite-2</b><hr>
 the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure)</td></tr>
+			<tr><td><b>RebuildGeometryTriggers</b></td>
+				<td>RebuildGeometryTriggers( table_name <i>String</i> , geometry_column_name <i>String</i> ) : <i>integer</i></td>
+				<td></td>
+				<td align="center" bgcolor="#d0f0d0">base</td>
+				<td>This function will reinstall all geometry-related Triggers for the named table.<hr>
+the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure)</td></tr>
+			<tr><td><b>UpgradeGeometryTriggers</b></td>
+				<td>UpgradeGeometryTriggers(  transaction <i>Integer</i>  ) : <i>integer</i></td>
+				<td></td>
+				<td align="center" bgcolor="#d0f0d0">base</td>
+				<td>This function will upgrade all geometry-related Triggers to the latest version 
+				(all DB tables declaring at least one Geometry will be affected by the upgrade).<br>
+				If the <b>transaction</b> argument is set to TRUE then the whole upgrade will be safely
+				executed within an internally defined SQL transaction.<hr>
+				<u>Please note</u>: DB-files created using obsolete versions of SpatiaLite (< 4.0.0) will not be upgraded.<hr>
+the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure)</td></tr>
 			<tr><td colspan="5" align="center" bgcolor="#f0f0c0">
 				<h3><a name="p16metacatalog">SQL functions supporting the MetaCatalog and related Statistics</a></h3></td></tr>
 			<tr><th bgcolor="#d0d0d0">Function</th>
@@ -3038,7 +3058,7 @@ the return type is Integer, with a return value of 1 for TRUE, 0 for FALSE</td><
 				<td align="center" bgcolor="#d0d0d0">geocallbacks</td>
 				<td>Retrieves from an R*Tree Spatial Index any entity whose MBR <u><i>intersect</i></u>
 				the square circumscribed on the given circle (<b>x y</b> center, <b>radius)</b></td></tr>
-                        <tr><td colspan="5" align="center" bgcolor="#f0f0c0">
+            <tr><td colspan="5" align="center" bgcolor="#f0f0c0">
 				<h3><a name="xmlBlob">SQL functions supporting XmlBLOB</a></h3></td></tr>
 			<tr><th bgcolor="#d0d0d0">Function</th>
 				<th bgcolor="#d0d0d0">Syntax</th>
@@ -3269,8 +3289,8 @@ the return type is Integer, with a return value of 1 for TRUE, 0 for FALSE</td><
 					This function is even able to acces a remote XML Document identified by an <b>URL</b>.<br>
 					Otherwise NULL will be returned.<br>
 					<u>Please note:</u> SQLite doesn't support BLOB values bigger than SQLITE_MAX_LENGTH (usually, 1 GB).<hr>
-                                        <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
-                                        Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.<br>
+                    <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                    Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.<br>
 					Please see: <b>CountUnsafeTriggers()</b></td></tr>
 			<tr><td><b>XB_StoreXML</b></td>
 				<td>XB_StoreXML( XmlObject <i>XmlBLOB</i> , filepath <i>String</i> ) : <i>Integer</i><hr>
@@ -3284,9 +3304,303 @@ the return type is Integer, with a return value of 1 for TRUE, 0 for FALSE</td><
                                 will be nicely formatted and properly indented by the required factor; <i>ZERO</i> will cause the whole 
                                 XmlDocument to be returned as a single line. (default setting is <i>negative</i> indenting, i.e. not reformatting at all).<hr>
 					The return type is Integer, with a return value of 1 for success, 0 for failure and -1 for invalid arguments.<hr>
-                                        <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
-                                        Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.<br>
+                    <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                    Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.<br>
 					Please see: <b>CountUnsafeTriggers()</b></td></tr>
+			<tr><td colspan="5" align="center" bgcolor="#f0e0c0">
+				<h3><a name="advanced">miscellaneous advanced SQL functions</a></h3></td></tr>
+			<tr><th bgcolor="#d0d0d0">Function</th>
+				<th bgcolor="#d0d0d0">Syntax</th>
+				<th bgcolor="#d0d0d0" colspan="3">Summary</th></tr>
+			<tr><td><b>CloneTable</b></td>
+				<td>CloneTable( db-prefix <i>Text</i> , input_table <i>Text</i> , output_table <i>Text</i> , 
+				transaction <i>Integer</i> ) : <i>Integer</i><hr>
+				CloneTable(  db-prefix <i>Text</i> , input_table <i>Text</i> , output_table <i>Text</i> , 
+				transaction <i>Integer</i> , option_1 <i>Text</i> [ , ... , option_10 <i>Text</i> ] ) : <i>Integer</i></td>
+				<td colspan="3">Will clone (i.e. create+copy) an origin table into a destination table: 
+				the origin could be eventually located into some <i>attached</i> DB, but the destination is always
+				assumed to be located into the primary DB</b>.<ul>
+				<li>Mandatory arguments:
+				<ul>
+					<li><b>db-prefix</b> corresponding to the origin; the primary DB always corresponds to the <i>main</i> prefix.</li>
+					<li><b>input_table</b> name of the origin table</li>
+					<li><b>output_table</b> name of the destination table</li>
+					<li><b>transaction</b> a <i>boolean</i> values stating if the whole operation has to be atomically confined
+					within a monolithic SQL transaction</li>
+				</ul></li>
+				<li>Optional arguments: a maximum of 10 further options could be eventually specified. Valid options are:
+				<ul>
+					<li><b>::with-foreign-keys::</b></li>
+					<li><b>::with-triggers::</b></li>
+					<li><b>::resequence::</b></li>
+					<li><b>::append::</b></li>
+					<li><b>::ignore::</b><i>column_name</i></li>
+					<li><b>::cast2multi::</b><i>geometry_column</i></li>
+				</ul></li>
+				</ul>
+				<hr>
+				Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success. <b>NULL</b> will be returned on invalid arguments.</td></tr>
+			<tr><td><b>CheckDuplicateRows</b></td>
+				<td>CheckDuplicateRows( table <i>Text</i> ) : <i>Integer</i></td>
+				<td colspan="3">Will check if the given <b>table</b> does contain duplicate rows, i.e. rows presenting identical 
+				values for all columns (ignoring any Primary Key column).
+				<hr>
+				Will return the total number of duplicate rows found.<br> <b>NULL</b> will be returned on invalid arguments.</td></tr>
+			<tr><td><b>RemoveDuplicateRows</b></td>
+				<td>RemoveDuplicateRows( table <i>Text</i> ) : <i>Integer</i></td>
+				<td colspan="3">Will remove all duplicate rows from the given <b>table</b> preserving only a songle occurrence.
+				<hr>
+				Will return the total number of deleted rows.<br> <b>NULL</b> will be returned on invalid arguments.</td></tr>
+			<tr><td><b>ElementaryGeometries</b></td>
+				<td>ElementaryGeometries( in_table <i>Text</i> , geom_column <i>Text</i> , out_table <i>Text</i> ,
+				out_pk <i>Text</i> , out_multi_id <i>Text</i> ) : <i>Integer</i></td>
+				<td colspan="3">Will create a new <b>out_table</b> directly corresponding to <b>in_table</b>.
+				The output table will be arranged in such a way that each row will always contain an elementary Geometry;
+				so each time that a <b>MULTI-type</b> Geometry is found in the input table it will be split into mamy
+				distinct rows.<br>
+				<b>out_pk</b> is the name to be set for the output Primary Key, and <b>out_multi_id</b> is the name to
+				be set for a second column within the output table where to store the original Primary Key.
+				<hr>
+				Will return the total number of rows inserted into the output table.<br> <b>NULL</b> will be returned on invalid arguments.</td></tr>
+			<tr><td><b>DropGeoTable</b></td>
+				<td>DropGeoTable( table <i>Text</i> ) : <i>Integer</i><hr>
+				DropGeoTable( db-prefix <i>Text</i> , table <i>Text</i> ) : <i>Integer</i></td>
+				<td colspan="3">Will completely remove a Geometry Table (or Spatial View) this including any eventual SpatialIndex,
+				metadata and statistics definitions an alike.
+				<hr>
+				Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success..<br> 
+				<b>NULL</b> will be returned on invalid arguments.</td></tr>
+			<tr><td><b>ImportSHP</b></td>
+				<td>ImportSHP( filename <i>Text</i> , table <i>Text</i> , charset <i>Text</i> ) : <i>Integer</i><hr>
+				ImportSHP( filename <i>Text</i> , table <i>Text</i> , charset <i>Text</i> [ , srid <i>Integer</i>  [ ,
+				    geom_column <i>Text</i> [ , pk_column <i>Text</i> [ , geometry_type <i>Text</i> [ , coerce2D <i>Integer</i> 
+				    [ , compressed <i>Integer</i> [ , spatial_index <i>Integer</i> [ , text_dats <i>Integer</i> ] ] ] ] ] ] ] ] )
+				    : <i>Integer</i></td>
+				<td colspan="3">Will import an external Shapfile into an internal Table:
+				<ul>
+				<li>Mandatory arguments:
+				<ul>
+					<li><b>filename</b> absolute or relative path leading to the Shapefile (omitting any <i>.shp</i>, <i>.shx</i> or <i>.dbf</i> suffix).</li>
+					<li><b>table</b> name of the table to be created.</li>
+					<li><b>charset</b> the character encoding adopted by the DBF member, as e.g. <i>UTF-8</i> or <i>CP1252</i></li>
+				</ul></li>
+				<li>Optional arguments:
+				<ul>
+					<li><b>srid</b> EPSG SRID value; <i>-1</i> by default.</li>
+					<li><b>geom_column</b> name to assigned to the Geometry column; <i>Geometry</i> by default.</li>
+					<li><b>pk_column</b> name of a DBF column to be used in the Primary Key role; an <i>INTEGER AUTOINCREMENT</i> 
+					PK will be created by default.</li>
+					<li><b>geometry_type</b> one between: <i>AUTO</i>, <i>POINT|Z|M|ZM</i>, <i>LINESTRING|Z|M|ZM</i>,
+						<i>POLYGON|Z|M|ZM</i>, <i>MULTIPOINT|Z|M|ZM</i>, <i>LINESTRING|Z|M|ZM</i>, <i>MULTIPOLYGON|Z|M|ZM</i>;
+						 by default <i>AUTO</i>.</li>
+					<li><b>coerce2D</b> boolean flag: casting to 2D or not; <i>0</i> by default.</li>
+					<li><b>compressed</b> boolean flag; compressed geometries or not; <i>0</i> by default.</li>
+					<li><b>spatial_index</b> boolean flag: immediately building a Spatial Index or not; <i>0</i> by default.</li>
+					<li><b>text_dates</b> boolean flag: interpreting DBF dates as plaintext or not: <i>0</i> by default
+					(i.e. as <i>Julian Day</i>).</li>
+				</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of imported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ExportSHP</b></td>
+				<td>ExportSHP( table <i>Text</i> , geom_column <i>Text</i> , filename <i>Text</i> , charset <i>Text</i> ) : <i>Integer</i><hr>
+				ExportSHP( table <i>Text</i> , geom_column <i>Text</i> , filename <i>Text</i> , charset <i>Text</i> , geom_type <i>Text</i>) : <i>Integer</i></td>
+				<td colspan="3">Will export an internal Table as an external Shapefile:
+				<ul>
+					<li><b>table</b> name of the table to be exported.</li>
+					<li><b>geom_column</b> name of the Geometry column.</li>
+					<li><b>filename</b> absolute or relative path leading to the Shapefile (omitting any <i>.shp</i>, <i>.shx</i> or <i>.dbf</i> suffix).</li>
+					<li><b>charset</b> the character encoding adopted by the DBF member, as e.g. <i>UTF-8</i> or <i>CP1252</i></li>
+					<li>the optional argument <b>geom_type</b> is useful when exporting unregistered Geometries, and
+					can be one between: <i>POINT</i>, <i>LINESTRING</i>, <i>POLYGON</i> or <i>MULTUPOINT</i>.</li>
+				</ul>
+				<hr>
+				Will return the total number of exported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ImportDBF</b></td>
+				<td>ImportDBF( filename <i>Text</i> , table <i>Text</i> , charset <i>Text</i> ) : <i>Integer</i><hr>
+				ImportDBF( filename <i>Text</i> , table <i>Text</i> , charset <i>Text</i> [ , pk_column <i>Text</i>  
+				    [ , text_dats <i>Integer</i> ] ] ) : <i>Integer</i></td>
+				<td colspan="3">Will import an external DBF file into an internal Table:
+				<ul>
+				<li>Mandatory arguments:
+				<ul>
+					<li><b>filename</b> absolute or relative path leading to the DBF (including the <i>.dbf</i> suffix).</li>
+					<li><b>table</b> name of the table to be created.</li>
+					<li><b>charset</b> the character encoding adopted by the DBF, as e.g. <i>UTF-8</i> or <i>CP1252</i></li>
+				</ul></li>
+				<li>Optional arguments:
+				<ul>
+					<li><b>pk_column</b> name of a DBF column to be used in the Primary Key role; an <i>INTEGER AUTOINCREMENT</i> 
+					PK will be created by default.</li>
+					<li><b>text_dates</b> boolean flag: interpreting DBF dates as plaintext or not: <i>0</i> by default
+					(i.e. as <i>Julian Day</i>).</li>
+				</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of imported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ExportDBF</b></td>
+				<td>ExportDBF( table <i>Text</i> , filename <i>Text</i> , charset <i>Text</i> ) : <i>Integer</i></td>
+				<td colspan="3">Will export an internal Table as an external DBF file:
+				<ul>
+					<li><b>table</b> name of the table to be exported.</li>
+					<li><b>filename</b> absolute or relative path leading to the DBF (including the <i>.dbf</i> suffix).</li>
+					<li><b>charset</b> the character encoding adopted by the DBF, as e.g. <i>UTF-8</i> or <i>CP1252</i></li>
+				</ul>
+				<hr>
+				Will return the total number of exported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ExportKML</b></td>
+				<td>ExportKML( table <i>Text</i> , geo_column <i>Text</i> , filename <i>Text</i> ) : <i>Integer</i><hr>
+				ExportKML( table <i>Text</i> , geo_column <i>Text</i> , filename <i>Text</i> [ , precision <i>Integer</i>
+				[ , name_column <i>Text</i> [ , description <i>Text</i> ] ] ] ) : <i>Integer</i></td>
+				<td colspan="3">Will export an internal Table as an external KML file:
+				<ul>
+					<li>Mandatory aguments:
+					<ul>
+						<li><b>table</b> name of the table to be exported.</li>
+						<li><b>geom_column</b> name of the Geometry column.</li>
+						<li><b>filename</b> absolute or relative path leading to the KML file.</li>
+					</ul></li>
+					<li>Optional aguments:
+					<ul>
+						<li><b>precision</b> number of decimal digits to be exported; <i>8</i> by default.</li>
+						<li><b>name_column</b> name of the table's column containing KML names.</li>
+						<li><b>description_column</b> name of the table's column containing KML descriptions.</li>
+					</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of exported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ExportGeoJSON</b></td>
+				<td>ExportGeoJSON( table <i>Text</i> , geo_column <i>Text</i> , filename <i>Text</i> ) : <i>Integer</i><hr>
+				ExportGeoJSON( table <i>Text</i> , geo_column <i>Text</i> , filename <i>Text</i> [ , format <i>Text</i>
+				[ , precision <i>Integer</i> ] ] ) : <i>Integer</i></td>
+				<td colspan="3">Will export an internal Table as an external GeoJSON file:
+				<ul>
+					<li>Mandatory aguments:
+					<ul>
+						<li><b>table</b> name of the table to be exported.</li>
+						<li><b>geom_column</b> name of the Geometry column.</li>
+						<li><b>filename</b> absolute or relative path leading to the GeoJSON file.</li>
+					</ul></li>
+					<li>Optional aguments:
+					<ul>
+						<li><b>format</b> specifies one of the several alternative GeoJSON formats; allowed values are
+						<i>none</i>, <i>MBR</i>, <i>withShortCRS</i>, <i>MBRwithShortCRS</i>, <i>withLongCRS</i>
+						or <i>MBRwithLongCRS</i>.</li>
+						<li><b>precision</b> number of decimal digits to be exported; <i>8</i> by default.</li>
+					</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of exported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ImportXLS</b></td>
+				<td>ImportXLS( filename <i>Text</i> , table <i>Text</i> ) : <i>Integer</i><hr>
+				ImportXLS( filename <i>Text</i> , table <i>Text</i> [ , worksheet_index <i>Integer</i>  
+				    [ , first_line_titles <i>Integer</i> ] ] ) : <i>Integer</i></td>
+				<td colspan="3">Will import an external spreadsheet file (<i>Microsoft .xls format</i>) into an internal Table:
+				<ul>
+				<li>Mandatory arguments:
+				<ul>
+					<li><b>filename</b> absolute or relative path leading to the spreadsheet file.</li>
+					<li><b>table</b> name of the table to be created.</li>
+				</ul></li>
+				<li>Optional arguments:
+				<ul>
+					<li><b>worksheet_index</b> a positive integer selecting the target worksheet in the case of a multi-sheet: <i>0</i> by default..</li>
+					<li><b>first_line_titles</b> boolean flag: the first line of the worksheet contains column names or not: <i>0</i> by default.</li>
+				</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of imported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ImportWFS</b></td>
+				<td>ImportWFS( filename_or_url <i>Text</i> , layer_name <i>Text</i> , table <i>Text</i> ) : <i>Integer</i><hr>
+				ImportXLS( filename_or_url <i>Text</i> , layer_name <i>Text</i> , table <i>Text</i> [ , pk_column <i>Text</i>  
+				    [ , swap_axes <i>Integer</i> [ , page_size <i>Integer</i> [ , spatial_index <i>Integer</i> ] ] ] ] ) : <i>Integer</i></td>
+				<td colspan="3">Will import data from a WFS datasource:
+				<ul>
+				<li>Mandatory arguments:
+				<ul>
+					<li><b>filename_or_url</b> absolute or relative path leading to the WFS file.<br>
+					Alternatively an URL corresponding to a WFS service.</li>
+					<li><b>layer_name</b> name of the WFS layer.</li>
+					<li><b>table</b> name of the table to be created.</li>
+				</ul></li>
+				<li>Optional arguments:
+				<ul>
+					<li><b>pk_column</b> name of a WFS column to be used in the Primary Key role; an <i>INTEGER AUTOINCREMENT</i> 
+					PK will be created by default.</li>
+					<li><b>swap_axes</b> boolean flag: swapping the <i>X</i> and <i>Y</i> axes or not: <i>0</i> by default.</li>
+					<li><b>page_size</b> : how many features for each WFS paged requests; a <i>negative</i> number or <i>zero</i> if
+					you don't intend to activate WFS paging. <i>-1</i> by default.</li>
+					<li><b>spatial_index</b> boolean flag: immediately building a Spatial Index or not; <i>0</i> by default.</li>
+				</ul></li>
+				</ul>
+				<hr>
+				Will return the total number of imported rows.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ImportDXF</b></td>
+				<td>ImportDXF( filename <i>String</i> ) : <i>Integer</i><hr>
+					ImportDXF( filename <i>String</i> [ , srid <i>Integer</i>, append <i>Integer</i>, dimensions <i>Text</i>,
+					mode <i>Text</i> , special_rings <i>Text</i> , table_prefix <i>Text</i> , layer_name <i>Text</i> ] ) : <i>Integer</i></td>
+				<td colspan="3">Will import an external DXF file.<ul>
+                    <li><b>filename</b> absolute or relative path leading to the DXF file.</li>
+					<li><b>srid</b> EPSG SRID value; <i>-1</i> by default.</li>
+					<li><b>append</b> boolean flag: enabling or not <i>append mode</i>: <i>0</i> by default.</li>
+					<li><b>dimensions</b> one between <i>AUTO</i>, <i>2D</i> or <i>3D</i>.</li>
+					<li><b>mode</b> one between <i>DISTINCT</i> or <i>MIXED</i>.</li>
+					<li><b>special_rings</b> one between <i>NONE</i>, <i>LINKED</i> or <i>UNLINKED</i>.</li>
+					<li><b>table_prefix</b>: a prefix for table names; <i>NULL</i> if no prefix is required.</li>
+					<li><b>layer_name</b>: name of a single DXF layer to be imported: <i>NULL</i> will import all layers found.</li>
+					</ul>
+					Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                    <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                    Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>
+			<tr><td><b>ImportDXFfromDir</b></td>
+				<td>ImportDXFfromDir( dir_path <i>String</i> ) : <i>Integer</i><hr>
+					ImportDXFfromDir( dir_path <i>String</i> [ , srid <i>Integer</i>, append <i>Integer</i>, dimensions <i>Text</i>,
+					mode <i>Text</i> , special_rings <i>Text</i> , table_prefix <i>Text</i> , layer_name <i>Text</i> ] ) : <i>Integer</i></td>
+				<td colspan="3">Will import all DXF files found within a given Directory.<ul>
+                    <li><b>dir_path</b> absolute or relative path leading to a directory containing all the <i>*.dxf</i> files to be imported.</li>
+					<li><b>srid</b> EPSG SRID value; <i>-1</i> by default.</li>
+					<li><b>append</b> boolean flag: enabling or not <i>append mode</i>: <i>0</i> by default.</li>
+					<li><b>dimensions</b> one between <i>AUTO</i>, <i>2D</i> or <i>3D</i>.</li>
+					<li><b>mode</b> one between <i>DISTINCT</i> or <i>MIXED</i>.</li>
+					<li><b>special_rings</b> one between <i>NONE</i>, <i>LINKED</i> or <i>UNLINKED</i>.</li>
+					<li><b>table_prefix</b>: a prefix for table names; <i>NULL</i> if no prefix is required.</li>
+					<li><b>layer_name</b>: name of a single DXF layer to be imported: <i>NULL</i> will import all layers found.</li>
+					</ul>
+					Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success.<br> <b>NULL</b> will be returned on invalid arguments.<hr>
+                    <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                    Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>		
+			<tr><td><b>ExportDXF</b></td>
+				<td>ExportDXF( out_dir <i>String</i> , filename <i>String</i> , sql_query <i>String</i> , layer_col_name <i>String</i> , 
+                geom_col_name <i>String</i> , label_col_name <i>String</i> , text_height_col_name <i>String</i> , 
+                text_rotation_col_name <i>String</i> , geom_filter <i>Geometry</i> [ , precision <i>Integer</i> ] ) : <i>Integer</i></td>
+				<td colspan="3">Will export a whole DXF file.<ul>
+                    <li>The output file path is controlled by <b>out_dir</b> and <b>filename</b>.</li>
+					<li><b>sql_query</b> is a complete SQL Statement returning the dataset to be exported.</li>
+					<li><b>layer_col_name</b>, <b>geom_col_name</b>, <b>label_col_name</b>, <b>text_height_col_name</b> 
+					and <b>text_rotation_col_name</b> must specify the corresponding <u>column names</u> within the resultset
+					returned by <b>sql_query</b> (<i>label_col_name</i>, <i>text_height_col_name</i> and <i>text_rotation_col_name</i> could be eventually <b>NULL</b>).</li>
+					<li><b>geom_filter</b> acts as a <u>spatial filter</u> selecting which entities have to be exported (could be <b>NULL</b>).</li>
+					<li>the optional argument <b>precision</b> specificies how many <u>decimal digits</u> are required for coordinate values: if not specified the default is <b>3</b>.</li>
+					</ul>
+					Will return <b>0</b> (i.e. <b>FALSE</b>) on failure, any other value (i.e. <b>TRUE</b>) on success.<hr>
+                    <u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always <i>disabled by default</i>.<br>
+                    Explicitly setting the environment variable <b>SPATIALITE_SECURITY=relaxed</b> is absolutely required in order to effectively enable this function.</td></tr>	
 		</tbody></table>
 		<a href="https://www.gaia-gis.it/fossil/libspatialite">back</a>
 	</body></html>
diff --git a/src/Makefile.am b/src/Makefile.am
index 4ebad26..a541d2e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,13 +36,14 @@ libspatialite_la_LIBADD = ./gaiaaux/libgaiaaux.la \
 
 if MINGW
 libspatialite_la_LDFLAGS = -version-info 4:2:0 -no-undefined
+libspatialite_la_LIBADD += -lm
 else 
 if ANDROID
-libspatialite_la_LDFLAGS = -version-info 7:0:0
-libspatialite_la_LIBADD += -ldl
+libspatialite_la_LDFLAGS = -version-info 7:0:1
+libspatialite_la_LIBADD += -ldl -lm
 else
-libspatialite_la_LDFLAGS = -version-info 7:0:0
-libspatialite_la_LIBADD += -lpthread -ldl
+libspatialite_la_LDFLAGS = -version-info 7:0:1
+libspatialite_la_LIBADD += -lpthread -ldl -lm
 endif
 endif
 
@@ -68,13 +69,14 @@ mod_spatialite_la_LIBTOOLFLAGS = --tag=disable-static
 
 if MINGW
 mod_spatialite_la_LDFLAGS = -module -avoid-version -no-undefined
+mod_spatialite_la_LIBADD += -lm
 else 
 if ANDROID
-mod_spatialite_la_LDFLAGS = -module -version-info 7:0:0
-mod_spatialite_la_LIBADD += -ldl
+mod_spatialite_la_LDFLAGS = -module -version-info 7:0:1
+mod_spatialite_la_LIBADD += -ldl -lm
 else
-mod_spatialite_la_LDFLAGS = -module -version-info 7:0:0
-mod_spatialite_la_LIBADD += -lpthread -ldl
+mod_spatialite_la_LDFLAGS = -module -version-info 7:0:1
+mod_spatialite_la_LIBADD += -lpthread -ldl -lm
 endif
 endif
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 0cf7db7..61ff519 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -78,10 +78,12 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
- at ANDROID_TRUE@@MINGW_FALSE at am__append_1 = -ldl
- at ANDROID_FALSE@@MINGW_FALSE at am__append_2 = -lpthread -ldl
- at ANDROID_TRUE@@MINGW_FALSE at am__append_3 = -ldl
- at ANDROID_FALSE@@MINGW_FALSE at am__append_4 = -lpthread -ldl
+ at MINGW_TRUE@am__append_1 = -lm
+ at ANDROID_TRUE@@MINGW_FALSE at am__append_2 = -ldl -lm
+ at ANDROID_FALSE@@MINGW_FALSE at am__append_3 = -lpthread -ldl -lm
+ at MINGW_TRUE@am__append_4 = -lm
+ at ANDROID_TRUE@@MINGW_FALSE at am__append_5 = -ldl -lm
+ at ANDROID_FALSE@@MINGW_FALSE at am__append_6 = -lpthread -ldl -lm
 subdir = src
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -133,7 +135,8 @@ libspatialite_la_DEPENDENCIES = ./gaiaaux/libgaiaaux.la \
 	./srsinit/libsrsinit.la \
 	./connection_cache/libconnection_cache.la \
 	./virtualtext/libvirtualtext.la ./wfs/libwfs.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_libspatialite_la_OBJECTS = version.lo
 libspatialite_la_OBJECTS = $(am_libspatialite_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
@@ -150,7 +153,8 @@ mod_spatialite_la_DEPENDENCIES = ./gaiaaux/gaiaaux.la \
 	./shapefiles/shapefiles.la ./dxf/dxf.la ./md5/md5.la \
 	./srsinit/srsinit.la ./connection_cache/connection_cache.la \
 	./virtualtext/virtualtext.la ./wfs/wfs.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_mod_spatialite_la_OBJECTS = mod_spatialite_la-version.lo
 mod_spatialite_la_OBJECTS = $(am_mod_spatialite_la_OBJECTS)
 mod_spatialite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@@ -414,9 +418,9 @@ libspatialite_la_LIBADD = ./gaiaaux/libgaiaaux.la \
 	./srsinit/libsrsinit.la \
 	./connection_cache/libconnection_cache.la \
 	./virtualtext/libvirtualtext.la ./wfs/libwfs.la @LIBXML2_LIBS@ \
-	$(am__append_1) $(am__append_2)
- at ANDROID_FALSE@@MINGW_FALSE at libspatialite_la_LDFLAGS = -version-info 7:0:0
- at ANDROID_TRUE@@MINGW_FALSE at libspatialite_la_LDFLAGS = -version-info 7:0:0
+	$(am__append_1) $(am__append_2) $(am__append_3)
+ at ANDROID_FALSE@@MINGW_FALSE at libspatialite_la_LDFLAGS = -version-info 7:0:1
+ at ANDROID_TRUE@@MINGW_FALSE at libspatialite_la_LDFLAGS = -version-info 7:0:1
 @MINGW_TRUE at libspatialite_la_LDFLAGS = -version-info 4:2:0 -no-undefined
 mod_spatialite_la_SOURCES = versioninfo/version.c
 mod_spatialite_la_LIBADD = ./gaiaaux/gaiaaux.la ./gaiaexif/gaiaexif.la \
@@ -425,12 +429,12 @@ mod_spatialite_la_LIBADD = ./gaiaaux/gaiaaux.la ./gaiaexif/gaiaexif.la \
 	./md5/md5.la ./srsinit/srsinit.la \
 	./connection_cache/connection_cache.la \
 	./virtualtext/virtualtext.la ./wfs/wfs.la @LIBXML2_LIBS@ \
-	$(am__append_3) $(am__append_4)
+	$(am__append_4) $(am__append_5) $(am__append_6)
 mod_spatialite_la_CPPFLAGS = @CFLAGS@ -I$(top_srcdir)/src/headers -I. \
 	-DLOADABLE_EXTENSION
 mod_spatialite_la_LIBTOOLFLAGS = --tag=disable-static
- at ANDROID_FALSE@@MINGW_FALSE at mod_spatialite_la_LDFLAGS = -module -version-info 7:0:0
- at ANDROID_TRUE@@MINGW_FALSE at mod_spatialite_la_LDFLAGS = -module -version-info 7:0:0
+ at ANDROID_FALSE@@MINGW_FALSE at mod_spatialite_la_LDFLAGS = -module -version-info 7:0:1
+ at ANDROID_TRUE@@MINGW_FALSE at mod_spatialite_la_LDFLAGS = -module -version-info 7:0:1
 @MINGW_TRUE at mod_spatialite_la_LDFLAGS = -module -avoid-version -no-undefined
 MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
 all: all-recursive
diff --git a/src/dxf/dxf_load_distinct.c b/src/dxf/dxf_load_distinct.c
index 6998709..c38b7e2 100644
--- a/src/dxf/dxf_load_distinct.c
+++ b/src/dxf/dxf_load_distinct.c
@@ -44,6 +44,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/dxf/dxf_load_mixed.c b/src/dxf/dxf_load_mixed.c
index e1f12ec..50c7ee5 100644
--- a/src/dxf/dxf_load_mixed.c
+++ b/src/dxf/dxf_load_mixed.c
@@ -44,6 +44,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/dxf/dxf_loader.c b/src/dxf/dxf_loader.c
index 8d32959..39b6fbd 100644
--- a/src/dxf/dxf_loader.c
+++ b/src/dxf/dxf_loader.c
@@ -44,6 +44,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/dxf/dxf_parser.c b/src/dxf/dxf_parser.c
index a4665b3..8ff54ef 100644
--- a/src/dxf/dxf_parser.c
+++ b/src/dxf/dxf_parser.c
@@ -43,6 +43,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/dxf/dxf_private.h b/src/dxf/dxf_private.h
index 6b38cfb..5ffd61a 100644
--- a/src/dxf/dxf_private.h
+++ b/src/dxf/dxf_private.h
@@ -42,6 +42,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 /**
  \file spatialite_private.h
 
diff --git a/src/dxf/dxf_writer.c b/src/dxf/dxf_writer.c
index 413c3f3..09878ca 100644
--- a/src/dxf/dxf_writer.c
+++ b/src/dxf/dxf_writer.c
@@ -44,6 +44,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+/*
+ 
+CREDITS:
+
+inital development of the DXF module has been funded by:
+Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
+
+*/
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/gaiaexif/gaia_exif.c b/src/gaiaexif/gaia_exif.c
index 621bb07..a904bc9 100644
--- a/src/gaiaexif/gaia_exif.c
+++ b/src/gaiaexif/gaia_exif.c
@@ -2375,6 +2375,8 @@ gaiaGuessBlobType (const unsigned char *blob, int size)
     unsigned char tiff_signature_big[4];
     unsigned char riff_signature[4];
     unsigned char webp_signature[8];
+    unsigned char jp2_little[12];
+    unsigned char jp2_big[12];
     jpeg1_signature[0] = 0xff;
     jpeg1_signature[1] = 0xd8;
     jpeg2_signature[0] = 0xff;
@@ -2423,6 +2425,30 @@ gaiaGuessBlobType (const unsigned char *blob, int size)
     webp_signature[5] = 'P';
     webp_signature[6] = '8';
     webp_signature[7] = ' ';
+    jp2_big[0] = 0x00;
+    jp2_big[1] = 0x00;
+    jp2_big[2] = 0x00;
+    jp2_big[3] = 0x0C;
+    jp2_big[4] = 0x6A;
+    jp2_big[5] = 0x50;
+    jp2_big[6] = 0x20;
+    jp2_big[7] = 0x20;
+    jp2_big[8] = 0x0D;
+    jp2_big[9] = 0x0A;
+    jp2_big[10] = 0x87;
+    jp2_big[11] = 0x0A;
+    jp2_little[0] = 0x00;
+    jp2_little[1] = 0x00;
+    jp2_little[2] = 0x0c;
+    jp2_little[3] = 0x00;
+    jp2_little[4] = 0x50;
+    jp2_little[5] = 0x6a;
+    jp2_little[6] = 0x20;
+    jp2_little[7] = 0x20;
+    jp2_little[8] = 0x0a;
+    jp2_little[9] = 0x0d;
+    jp2_little[10] = 0x0a;
+    jp2_little[11] = 0x87;
     if (size < 1 || !blob)
 	return GAIA_HEX_BLOB;
     if (size > 4)
@@ -2453,6 +2479,13 @@ gaiaGuessBlobType (const unsigned char *blob, int size)
 	  if (memcmp (blob, png_signature, 8) == 0)
 	      return GAIA_PNG_BLOB;
       }
+    if (size > 12)
+      {
+	  if (memcmp (blob, jp2_big, 12) == 0)
+	      return GAIA_JP2_BLOB;
+	  if (memcmp (blob, jp2_little, 12) == 0)
+	      return GAIA_JP2_BLOB;
+      }
     if (size > 4)
       {
 	  if (memcmp (blob, jpeg1_signature, 2) == 0
diff --git a/src/gaiageo/gg_advanced.c b/src/gaiageo/gg_advanced.c
index 0c54e5f..5ff2157 100644
--- a/src/gaiageo/gg_advanced.c
+++ b/src/gaiageo/gg_advanced.c
@@ -1471,14 +1471,14 @@ gaiaDissolveSegments (gaiaGeomCollPtr geom)
     gaiaRingPtr rng;
     int iv;
     int ib;
-    double x;
-    double y;
-    double z;
-    double m;
-    double x0;
-    double y0;
-    double z0;
-    double m0;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
+    double x0 = 0.0;
+    double y0 = 0.0;
+    double z0 = 0.0;
+    double m0 = 0.0;
     if (!geom)
 	return NULL;
 
@@ -1752,10 +1752,10 @@ gaiaDissolvePoints (gaiaGeomCollPtr geom)
     gaiaRingPtr rng;
     int iv;
     int ib;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     if (!geom)
 	return NULL;
 
diff --git a/src/gaiageo/gg_geometries.c b/src/gaiageo/gg_geometries.c
index b95b3b1..bb0c607 100644
--- a/src/gaiageo/gg_geometries.c
+++ b/src/gaiageo/gg_geometries.c
@@ -3469,17 +3469,17 @@ gaiaMakeLine (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
     gaiaLinestringPtr ln;
     gaiaPolygonPtr pg;
     gaiaGeomCollPtr g;
-    int dims0;
-    int dims1;
+    int dims0 = 0;
+    int dims1 = 0;
     int dims;
-    double x0;
-    double y0;
-    double z0;
-    double m0;
-    double x1;
-    double y1;
-    double z1;
-    double m1;
+    double x0 = 0.0;
+    double y0 = 0.0;
+    double z0 = 0.0;
+    double m0 = 0.0;
+    double x1 = 0.0;
+    double y1 = 0.0;
+    double z1 = 0.0;
+    double m1 = 0.0;
 
 /* checking if GEOM-1 simply is a POINT */
     if (geom1 == NULL)
diff --git a/src/gaiageo/gg_geoscvt.c b/src/gaiageo/gg_geoscvt.c
index 12bad90..06a8a5c 100644
--- a/src/gaiageo/gg_geoscvt.c
+++ b/src/gaiageo/gg_geoscvt.c
@@ -82,14 +82,14 @@ toGeosGeometry (const void *cache, GEOSContextHandle_t handle,
     double y;
     double z;
     double m;
-    double x0;
-    double y0;
-    double z0;
+    double x0 = 0.0;
+    double y0 = 0.0;
+    double z0 = 0.0;
     gaiaPointPtr pt;
     gaiaLinestringPtr ln;
     gaiaPolygonPtr pg;
     gaiaRingPtr rng;
-    GEOSGeometry *geos;
+    GEOSGeometry *geos = NULL;
     GEOSGeometry *geos_ext;
     GEOSGeometry *geos_int;
     GEOSGeometry *geos_item;
diff --git a/src/gaiageo/gg_gml.c b/src/gaiageo/gg_gml.c
index 66036bb..86421d6 100644
--- a/src/gaiageo/gg_gml.c
+++ b/src/gaiageo/gg_gml.c
@@ -1036,7 +1036,7 @@ gml_extract_multi_coord (const char *value, double *x, double *y, double *z,
     const char *in = value;
     char buf[1024];
     char *out = buf;
-    int last;
+    int last = ' ';
     *out = '\0';
     while (*in != '\0')
       {
@@ -1155,7 +1155,7 @@ gml_parse_coordinates (gmlCoordPtr coord, gaiaDynamicLinePtr dyn, int *has_z)
     double x;
     double y;
     double z;
-    gmlCoordPtr next;
+    gmlCoordPtr next = NULL;
     gmlCoordPtr c = coord;
     while (c)
       {
@@ -1184,9 +1184,9 @@ gml_parse_posList (gmlCoordPtr coord, gaiaDynamicLinePtr dyn, int has_z)
 {
 /* parsing GML v3.x <gml:posList> [Linestring or Ring] */
     int count = 0;
-    double x;
-    double y;
-    double z;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
     gmlCoordPtr c = coord;
     while (c)
       {
@@ -2604,9 +2604,9 @@ gml_validate_geometry (const void *cache, struct gml_data *p_data,
     gaiaPointPtr pt;
     gaiaLinestringPtr ln;
     gaiaPolygonPtr pg;
-    gaiaPointPtr save_pt;
-    gaiaLinestringPtr save_ln;
-    gaiaPolygonPtr save_pg;
+    gaiaPointPtr save_pt = NULL;
+    gaiaLinestringPtr save_ln = NULL;
+    gaiaPolygonPtr save_pg = NULL;
     gaiaRingPtr i_ring;
     gaiaRingPtr o_ring;
     int ib;
diff --git a/src/gaiageo/gg_kml.c b/src/gaiageo/gg_kml.c
index 9cf48a7..fdb723e 100644
--- a/src/gaiageo/gg_kml.c
+++ b/src/gaiageo/gg_kml.c
@@ -860,7 +860,7 @@ kml_extract_multi_coord (const char *value, double *x, double *y, double *z,
     const char *in = value;
     char buf[1024];
     char *out = buf;
-    int last;
+    int last = 0;
     *out = '\0';
     while (*in != '\0')
       {
@@ -979,7 +979,7 @@ kml_parse_coordinates (kmlCoordPtr coord, gaiaDynamicLinePtr dyn, int *has_z)
     double x;
     double y;
     double z;
-    kmlCoordPtr next;
+    kmlCoordPtr next = NULL;
     kmlCoordPtr c = coord;
     while (c)
       {
@@ -1450,9 +1450,9 @@ kml_validate_geometry (struct kml_data *p_data, gaiaGeomCollPtr chain)
     gaiaPointPtr pt;
     gaiaLinestringPtr ln;
     gaiaPolygonPtr pg;
-    gaiaPointPtr save_pt;
-    gaiaLinestringPtr save_ln;
-    gaiaPolygonPtr save_pg;
+    gaiaPointPtr save_pt = NULL;
+    gaiaLinestringPtr save_ln = NULL;
+    gaiaPolygonPtr save_pg = NULL;
     gaiaRingPtr i_ring;
     gaiaRingPtr o_ring;
     int ib;
diff --git a/src/gaiageo/gg_lwgeom.c b/src/gaiageo/gg_lwgeom.c
index 15c9748..2d444b3 100644
--- a/src/gaiageo/gg_lwgeom.c
+++ b/src/gaiageo/gg_lwgeom.c
@@ -258,10 +258,10 @@ toLWGeom (const gaiaGeomCollPtr gaia)
     int ib;
     int iv;
     int type;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     int close_ring;
     gaiaPointPtr pt;
     gaiaLinestringPtr ln;
@@ -1662,10 +1662,10 @@ toLWGeomLinestring (gaiaLinestringPtr ln, int srid)
 {
 /* converting a GAIA Linestring into a LWGEOM Geometry */
     int iv;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     int has_z = 0;
     int has_m = 0;
     POINTARRAY *pa;
@@ -1712,10 +1712,10 @@ toLWGeomPolygon (gaiaPolygonPtr pg, int srid)
 /* converting a GAIA Linestring into a LWGEOM Geometry */
     int iv;
     int ib;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     int ngeoms;
     int has_z = 0;
     int has_m = 0;
diff --git a/src/gaiageo/gg_relations_ext.c b/src/gaiageo/gg_relations_ext.c
index ba04aea..16dae51 100644
--- a/src/gaiageo/gg_relations_ext.c
+++ b/src/gaiageo/gg_relations_ext.c
@@ -3606,10 +3606,10 @@ rotateRingBeforeCut (gaiaLinestringPtr ln, gaiaPointPtr node)
     int iv;
     int copy = 0;
     int base_idx = -1;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     gaiaLinestringPtr new_ln = NULL;
 
     if (ln->DimensionModel == GAIA_XY_Z)
@@ -3825,10 +3825,10 @@ cutLineAtNodes (gaiaLinestringPtr ln, gaiaPointPtr pt_base,
     int match = 0;
     int iv;
     int i_start;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     gaiaPointPtr pt;
     gaiaPointPtr node = NULL;
 
diff --git a/src/gaiageo/gg_shape.c b/src/gaiageo/gg_shape.c
index cff706c..612c0e1 100644
--- a/src/gaiageo/gg_shape.c
+++ b/src/gaiageo/gg_shape.c
@@ -1287,7 +1287,8 @@ to_sqlite_julian_date (int year, int month, int day, double *julian)
 }
 
 static int
-parseDbfField (unsigned char *buf_dbf, void *iconv_obj, gaiaDbfFieldPtr pFld)
+parseDbfField (unsigned char *buf_dbf, void *iconv_obj, gaiaDbfFieldPtr pFld,
+	       int text_dates)
 {
 /* parsing a generic DBF field */
     unsigned char buf[512];
@@ -1328,34 +1329,43 @@ parseDbfField (unsigned char *buf_dbf, void *iconv_obj, gaiaDbfFieldPtr pFld)
 	  else if (pFld->Type == 'D')
 	    {
 		/* DATE value */
-		if (strlen ((char *) buf) != 8)
-		    gaiaSetNullValue (pFld);
+		if (text_dates)
+		  {
+		      /* assuming to be plain text */
+		      gaiaSetStrValue (pFld, (char *) buf);
+		  }
 		else
 		  {
-		      /* converting into a Julian Date */
-		      double julian;
-		      char date[5];
-		      int year = 0;
-		      int month = 0;
-		      int day = 0;
-		      date[0] = buf[0];
-		      date[1] = buf[1];
-		      date[2] = buf[2];
-		      date[3] = buf[3];
-		      date[4] = '\0';
-		      year = atoi (date);
-		      date[0] = buf[4];
-		      date[1] = buf[5];
-		      date[2] = '\0';
-		      month = atoi (date);
-		      date[0] = buf[6];
-		      date[1] = buf[7];
-		      date[2] = '\0';
-		      day = atoi (date);
-		      if (to_sqlite_julian_date (year, month, day, &julian))
-			  gaiaSetDoubleValue (pFld, julian);
-		      else
+		      if (strlen ((char *) buf) != 8)
 			  gaiaSetNullValue (pFld);
+		      else
+			{
+			    /* converting into a Julian Date */
+			    double julian;
+			    char date[5];
+			    int year = 0;
+			    int month = 0;
+			    int day = 0;
+			    date[0] = buf[0];
+			    date[1] = buf[1];
+			    date[2] = buf[2];
+			    date[3] = buf[3];
+			    date[4] = '\0';
+			    year = atoi (date);
+			    date[0] = buf[4];
+			    date[1] = buf[5];
+			    date[2] = '\0';
+			    month = atoi (date);
+			    date[0] = buf[6];
+			    date[1] = buf[7];
+			    date[2] = '\0';
+			    day = atoi (date);
+			    if (to_sqlite_julian_date
+				(year, month, day, &julian))
+				gaiaSetDoubleValue (pFld, julian);
+			    else
+				gaiaSetNullValue (pFld);
+			}
 		  }
 	    }
 	  else if (pFld->Type == 'L')
@@ -1611,6 +1621,13 @@ shp_build_area (struct shp_ring_collection *ringsColl, gaiaGeomCollPtr geom)
 GAIAGEO_DECLARE int
 gaiaReadShpEntity (gaiaShapefilePtr shp, int current_row, int srid)
 {
+    return gaiaReadShpEntity_ex (shp, current_row, srid, 0);
+}
+
+GAIAGEO_DECLARE int
+gaiaReadShpEntity_ex (gaiaShapefilePtr shp, int current_row, int srid,
+		      int text_dates)
+{
 /* trying to read an entity from shapefile */
     unsigned char buf[512];
     int len;
@@ -2491,7 +2508,7 @@ gaiaReadShpEntity (gaiaShapefilePtr shp, int current_row, int srid)
     pFld = shp->Dbf->First;
     while (pFld)
       {
-	  if (!parseDbfField (shp->BufDbf, shp->IconvObj, pFld))
+	  if (!parseDbfField (shp->BufDbf, shp->IconvObj, pFld, text_dates))
 	      goto conversion_error;
 	  pFld = pFld->Next;
       }
@@ -2686,8 +2703,8 @@ gaiaWriteShpEntity (gaiaShapefilePtr shp, gaiaDbfListPtr entity)
 #endif
     size_t len;
     size_t utf8len;
+    char *dynbuf;
     char *pUtf8buf;
-    char buf[512];
     char utf8buf[2048];
 /* writing the DBF record */
     memset (shp->BufDbf, '\0', shp->DbfReclen);
@@ -2729,23 +2746,33 @@ gaiaWriteShpEntity (gaiaShapefilePtr shp, gaiaDbfListPtr entity)
 		  {
 		      if (fld->Value->Type == GAIA_TEXT_VALUE)
 			{
-			    strcpy (buf, fld->Value->TxtValue);
-			    len = strlen (buf);
+			    len = strlen (fld->Value->TxtValue);
+			    dynbuf = malloc (len + 1);
+			    strcpy (dynbuf, fld->Value->TxtValue);
+			    if (len > 512)
+			      {
+				  dynbuf[512] = '\0';
+				  len = strlen (dynbuf);
+			      }
 			    utf8len = 2048;
-			    pBuf = buf;
+			    pBuf = dynbuf;
 			    pUtf8buf = utf8buf;
 			    if (iconv
 				((iconv_t) (shp->IconvObj), &pBuf, &len,
 				 &pUtf8buf, &utf8len) == (size_t) (-1))
-				goto conversion_error;
-			    memcpy (buf, utf8buf, 2048 - utf8len);
-			    buf[2048 - utf8len] = '\0';
-			    if (strlen (buf) < fld->Length)
-				memcpy (shp->BufDbf + fld->Offset + 1, buf,
-					strlen (buf));
+			      {
+				  free (dynbuf);
+				  goto conversion_error;
+			      }
+			    memcpy (dynbuf, utf8buf, 2048 - utf8len);
+			    dynbuf[2048 - utf8len] = '\0';
+			    if (strlen (dynbuf) < fld->Length)
+				memcpy (shp->BufDbf + fld->Offset + 1, dynbuf,
+					strlen (dynbuf));
 			    else
-				memcpy (shp->BufDbf + fld->Offset + 1, buf,
+				memcpy (shp->BufDbf + fld->Offset + 1, dynbuf,
 					fld->Length);
+			    free (dynbuf);
 			}
 		  }
 		break;
@@ -5139,6 +5166,13 @@ gaiaFlushDbfHeader (gaiaDbfPtr dbf)
 GAIAGEO_DECLARE int
 gaiaReadDbfEntity (gaiaDbfPtr dbf, int current_row, int *deleted)
 {
+    return gaiaReadDbfEntity_ex (dbf, current_row, deleted, 0);
+}
+
+GAIAGEO_DECLARE int
+gaiaReadDbfEntity_ex (gaiaDbfPtr dbf, int current_row, int *deleted,
+		      int text_dates)
+{
 /* trying to read an entity from DBF */
     int rd;
     int skpos;
@@ -5171,7 +5205,7 @@ gaiaReadDbfEntity (gaiaDbfPtr dbf, int current_row, int *deleted)
     pFld = dbf->Dbf->First;
     while (pFld)
       {
-	  if (!parseDbfField (dbf->BufDbf, dbf->IconvObj, pFld))
+	  if (!parseDbfField (dbf->BufDbf, dbf->IconvObj, pFld, text_dates))
 	      goto conversion_error;
 	  pFld = pFld->Next;
       }
diff --git a/src/gaiageo/gg_transform.c b/src/gaiageo/gg_transform.c
index ef0e178..ee5dd75 100644
--- a/src/gaiageo/gg_transform.c
+++ b/src/gaiageo/gg_transform.c
@@ -772,10 +772,10 @@ gaiaNormalizeLonLat (gaiaGeomCollPtr geom)
 */
     int ib;
     int iv;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     gaiaPointPtr point;
     gaiaPolygonPtr polyg;
     gaiaLinestringPtr line;
diff --git a/src/gaiageo/gg_voronoj.c b/src/gaiageo/gg_voronoj.c
index fdc1d83..fb6842c 100644
--- a/src/gaiageo/gg_voronoj.c
+++ b/src/gaiageo/gg_voronoj.c
@@ -652,7 +652,7 @@ voronoj_build_r (const void *p_cache, int count, void *p_first,
     double mx;
     double my;
     double slope;
-    double intercept;
+    double intercept = 0.0;
     double minx = DBL_MAX;
     double miny = DBL_MAX;
     double maxx = DBL_MIN;
diff --git a/src/gaiageo/gg_wkt.c b/src/gaiageo/gg_wkt.c
index 0b4b891..56ca504 100644
--- a/src/gaiageo/gg_wkt.c
+++ b/src/gaiageo/gg_wkt.c
@@ -2627,10 +2627,10 @@ static void
 out_kml_point (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
 {
 /* formats POINT as KML [x,y] */
-    char *buf_x;
-    char *buf_y;
-    char *buf_z;
-    char *buf;
+    char *buf_x = NULL;
+    char *buf_y = NULL;
+    char *buf_z = NULL;
+    char *buf = NULL;
     buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
     gaiaOutClean (buf_x);
     buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
@@ -2662,15 +2662,15 @@ out_kml_linestring (gaiaOutBuffer * out_buf, int dims, int points,
 		    double *coords, int precision)
 {
 /* formats LINESTRING as KML [x,y] */
-    char *buf_x;
-    char *buf_y;
-    char *buf_z;
-    char *buf;
+    char *buf_x = NULL;
+    char *buf_y = NULL;
+    char *buf_z = NULL;
+    char *buf = NULL;
     int iv;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     gaiaAppendToOutBuffer (out_buf, "<LineString><coordinates>");
     for (iv = 0; iv < points; iv++)
       {
@@ -2725,17 +2725,17 @@ out_kml_polygon (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polygon,
 		 int precision)
 {
 /* formats POLYGON as KML [x,y] */
-    char *buf_x;
-    char *buf_y;
-    char *buf_z;
-    char *buf;
+    char *buf_x = NULL;
+    char *buf_y = NULL;
+    char *buf_z = NULL;
+    char *buf = NULL;
     gaiaRingPtr ring;
     int iv;
     int ib;
-    double x;
-    double y;
-    double z;
-    double m;
+    double x = 0.0;
+    double y = 0.0;
+    double z = 0.0;
+    double m = 0.0;
     gaiaAppendToOutBuffer (out_buf, "<Polygon>");
     gaiaAppendToOutBuffer (out_buf,
 			   "<outerBoundaryIs><LinearRing><coordinates>");
diff --git a/src/gaiageo/gg_xml.c b/src/gaiageo/gg_xml.c
index a142673..8c32d02 100644
--- a/src/gaiageo/gg_xml.c
+++ b/src/gaiageo/gg_xml.c
@@ -946,10 +946,10 @@ find_iso_geometry (xmlNodePtr node, gaiaGeomCollPtr * geom)
 			       /                    <geographicElement>
 			       /                      <EX_GeographicBoundingBox> 
 			     */
-			    double minx;
-			    double maxx;
-			    double miny;
-			    double maxy;
+			    double minx = 0.0;
+			    double maxx = 0.0;
+			    double miny = 0.0;
+			    double maxy = 0.0;
 			    if (parse_bounding_box
 				(cur_node, &minx, &miny, &maxx, &maxy))
 			      {
@@ -1459,7 +1459,7 @@ gaiaXmlToBlob (const void *p_cache, const unsigned char *xml, int xml_len,
 /* attempting to build an XmlBLOB buffer */
     xmlDocPtr xml_doc;
     xmlDocPtr schema_doc;
-    xmlSchemaPtr schema;
+    xmlSchemaPtr schema = NULL;
     xmlSchemaParserCtxtPtr parser_ctxt;
     xmlSchemaValidCtxtPtr valid_ctxt;
     int is_iso_metadata = 0;
diff --git a/src/geopackage/gaia_cvt_gpkg.c b/src/geopackage/gaia_cvt_gpkg.c
index 2702fca..1cb1e3b 100644
--- a/src/geopackage/gaia_cvt_gpkg.c
+++ b/src/geopackage/gaia_cvt_gpkg.c
@@ -928,9 +928,9 @@ copy_spatialite2GPKG (sqlite3 * handle_in, sqlite3 * handle_out, int legacy)
       {
 	  for (i = 1; i <= rows; i++)
 	    {
-		const char *table_name;
-		const char *geometry_column;
-		const char *geometry_type;
+		const char *table_name = NULL;
+		const char *geometry_column = NULL;
+		const char *geometry_type = NULL;
 		int has_z = 0;
 		int has_m = 0;
 		int srid;
diff --git a/src/headers/spatialite.h b/src/headers/spatialite.h
index fdf6091..c27d4e2 100644
--- a/src/headers/spatialite.h
+++ b/src/headers/spatialite.h
@@ -193,7 +193,7 @@ extern "C"
  \param charset a valid GNU ICONV charset to be used for DBF text strings
  \param geom_type "POINT", "LINESTRING", "POLYGON", "MULTIPOLYGON" or NULL
  \param verbose if TRUE a short report is shown on stderr
- \param rows on completion will contain the total number of actually exported rows
+ \param rows on completion will contain the total number of exported rows
  \param err_msg on completion will contain an error message (if any)
 
  \return 0 on failure, any other value on success
@@ -217,12 +217,12 @@ extern "C"
  \param compressed if TRUE compressed Geometries will be created
  \param verbose if TRUE a short report is shown on stderr
  \param spatial_index if TRUE an R*Tree Spatial Index will be created
- \param rows on completion will contain the total number of actually exported rows
+ \param rows on completion will contain the total number of imported rows
  \param err_msg on completion will contain an error message (if any)
 
  \return 0 on failure, any other value on success
 
- \sa load_shapefile_ex
+ \sa load_shapefile_ex, load_shapefile_ex2
 
  \note this function simply calls load_shapefile_ex by passing 
   implicit gype="AUTO" and pk_column=NULL arguments
@@ -254,12 +254,12 @@ extern "C"
  \param compressed if TRUE compressed Geometries will be created
  \param verbose if TRUE a short report is shown on stderr
  \param spatial_index if TRUE an R*Tree Spatial Index will be created
- \param rows on completion will contain the total number of actually exported rows
+ \param rows on completion will contain the total number of imported rows
  \param err_msg on completion will contain an error message (if any)
 
  \return 0 on failure, any other value on success
 
- \sa load_shapefile
+ \sa load_shapefile, load_shapefile_ex2
 
  \note the Shapefile format doesn't supports any distinction between
   LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
@@ -279,6 +279,52 @@ extern "C"
 					      int *rows, char *err_msg);
 
 /**
+ Loads an external Shapefile into a newly created table
+
+ \param sqlite handle to current DB connection
+ \param shp_path pathname of the Shapefile to be imported (no suffix) 
+ \param table the name of the table to be created
+ \param charset a valid GNU ICONV charset to be used for DBF text strings
+ \param srid the SRID to be set for Geometries
+ \param geo_column the name of the geometry column
+ \param gtype expected to be one of: "LINESTRING", "LINESTRINGZ", 
+  "LINESTRINGM", "LINESTRINGZM", "MULTILINESTRING", "MULTILINESTRINGZ",
+  "MULTILINESTRINGM", "MULTILINESTRINGZM", "POLYGON", "POLYGONZ", "POLYGONM", 
+  "POLYGONZM", "MULTIPOLYGON", "MULTIPOLYGONZ", "MULTIPOLYGONM", 
+  "MULTIPOLYGONZM" or "AUTO".
+ \param pk_column name of the Primary Key column; if NULL or mismatching
+ then "PK_UID" will be assumed by default.
+ \param coerce2d if TRUE any Geometry will be casted to 2D [XY]
+ \param compressed if TRUE compressed Geometries will be created
+ \param verbose if TRUE a short report is shown on stderr
+ \param spatial_index if TRUE an R*Tree Spatial Index will be created
+ \param text_dates is TRUE all DBF dates will be considered as TEXT
+ \param rows on completion will contain the total number of imported rows
+ \param err_msg on completion will contain an error message (if any)
+
+ \return 0 on failure, any other value on success
+
+ \sa load_shapefile, load_shapefile_ex
+
+ \note the Shapefile format doesn't supports any distinction between
+  LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
+  as does not allows to clearly distinguish if the M-measure is required.
+ \n So a first preliminary scan of the Shapefile is required in order to
+  correctly identify the actual payload (gtype = "AUTO", default case).
+ \n By explicitly specifying some expected geometry type this first scan
+  will be skipped at all thus introducing a noticeable performance gain.
+ \n Anyway, declaring a mismatching geometry type will surely cause a failure.
+ */
+    SPATIALITE_DECLARE int load_shapefile_ex2 (sqlite3 * sqlite, char *shp_path,
+					       char *table, char *charset,
+					       int srid, char *geo_column,
+					       char *gtype, char *pk_column,
+					       int coerce2d, int compressed,
+					       int verbose, int spatial_index,
+					       int text_date, int *rows,
+					       char *err_msg);
+
+/**
  Loads an external DBF file into a newly created table
 
  \param sqlite handle to current DB connection
@@ -289,7 +335,7 @@ extern "C"
  \param rows on completion will contain the total number of actually exported rows
  \param err_msg on completion will contain an error message (if any)
 
- \sa load_dbf_ex
+ \sa load_dbf_ex, load_dbf_ex2
 
  \note this function simply calls load_dbf_ex by passing an
   implicit pk_column=NULL argument
@@ -313,7 +359,7 @@ extern "C"
  \param rows on completion will contain the total number of actually exported rows
  \param err_msg on completion will contain an error message (if any)
 
- \sa load_shapefile
+ \sa load_dbf, load_dbf_ex2
 
  \return 0 on failure, any other value on success
  */
@@ -322,6 +368,29 @@ extern "C"
 					char *charset, int verbose, int *rows,
 					char *err_msg);
 
+/**
+ Loads an external DBF file into a newly created table
+
+ \param sqlite handle to current DB connection
+ \param dbf_path pathname of the DBF file to be imported
+ \param table the name of the table to be created
+ \param pk_column name of the Primary Key column; if NULL or mismatching
+ then "PK_UID" will be assumed by default.
+ \param charset a valid GNU ICONV charset to be used for DBF text strings
+ \param verbose if TRUE a short report is shown on stderr
+ \param text_dates is TRUE all DBF dates will be considered as TEXT
+ \param rows on completion will contain the total number of imported rows
+ \param err_msg on completion will contain an error message (if any)
+
+ \sa load_dbf, load_dbf_ex
+
+ \return 0 on failure, any other value on success
+ */
+    SPATIALITE_DECLARE int load_dbf_ex2 (sqlite3 * sqlite, char *dbf_path,
+					 char *table, char *pk_column,
+					 char *charset, int verbose,
+					 int text_date, int *rows,
+					 char *err_msg);
 
 /**
  Dumps a full table into an external DBF file
@@ -331,6 +400,8 @@ extern "C"
  \param dbf_path pathname of the DBF to be exported 
  \param charset a valid GNU ICONV charset to be used for DBF text strings
  \param err_msg on completion will contain an error message (if any)
+ 
+ \sa dump_dbf_ex
 
  \return 0 on failure, any other value on success
  */
@@ -339,6 +410,24 @@ extern "C"
 				     char *err_msg);
 
 /**
+ Dumps a full table into an external DBF file
+
+ \param sqlite handle to current DB connection
+ \param table the name of the table to be exported
+ \param dbf_path pathname of the DBF to be exported 
+ \param charset a valid GNU ICONV charset to be used for DBF text strings
+ \param rows on completion will contain the total number of exported rows
+ \param err_msg on completion will contain an error message (if any)
+ 
+ \sa dump_dbf
+
+ \return 0 on failure, any other value on success
+ */
+    SPATIALITE_DECLARE int dump_dbf_ex (sqlite3 * sqlite, char *table,
+					char *dbf_path, char *charset,
+					int *rows, char *err_msg);
+
+/**
  Loads an external spreadsheet (.xls) file into a newly created table
 
  \param sqlite handle to current DB connection
@@ -441,6 +530,8 @@ extern "C"
  \param name_col column to be used for KML "name" (may be null)
  \param desc_col column to be used for KML "description" (may be null)
  \param precision number of decimal digits for coordinates
+ 
+ \sa dump_kml_ex
 
  \return 0 on failure, any other value on success
  */
@@ -450,6 +541,27 @@ extern "C"
 				     int precision);
 
 /**
+ Dumps a full geometry-table into an external KML file
+
+ \param sqlite handle to current DB connection
+ \param table the name of the table to be exported
+ \param geom_col the name of the geometry column
+ \param kml_path pathname of the KML file to be exported 
+ \param name_col column to be used for KML "name" (may be null)
+ \param desc_col column to be used for KML "description" (may be null)
+ \param precision number of decimal digits for coordinates
+ \param rows on completion will contain the total number of exported rows
+ 
+ \sa dump_kml
+
+ \return 0 on failure, any other value on success
+ */
+    SPATIALITE_DECLARE int dump_kml_ex (sqlite3 * sqlite, char *table,
+					char *geom_col, char *kml_path,
+					char *name_col, char *desc_col,
+					int precision, int *rows);
+
+/**
  Checks for duplicated rows into the same table
 
  \param sqlite handle to current DB connection
@@ -505,6 +617,8 @@ extern "C"
  \param outTable name of the output table to be created
  \param pKey name of the Primary Key column in the output table
  \param multiId name of the column identifying origins in the output table
+ 
+ \sa elementary_geometries_ex
 
  \note if the input table contains some kind of complex Geometry
  (MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
@@ -520,6 +634,33 @@ extern "C"
 						   char *multiId);
 
 /**
+ Creates a derived table surely containing elementary Geometries
+
+ \param sqlite handle to current DB connection
+ \param inTable name of the input table 
+ \param geometry name of the Geometry column
+ \param outTable name of the output table to be created
+ \param pKey name of the Primary Key column in the output table
+ \param multiId name of the column identifying origins in the output table
+ \param rows on completion will contain the total number of inserted rows
+ 
+ \sa elementary_geometries
+
+ \note if the input table contains some kind of complex Geometry
+ (MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
+ then many rows are inserted into the output table: each single 
+ row will contain the same attributes and an elementaty Geometry.
+ All the rows created by expanding the same input row will expose
+ the same value in the "multiId" column.
+ */
+    SPATIALITE_DECLARE void elementary_geometries_ex (sqlite3 * sqlite,
+						      char *inTable,
+						      char *geometry,
+						      char *outTable,
+						      char *pKey, char *multiId,
+						      int *rows);
+
+/**
  Dumps a full geometry-table into an external GeoJSON file
 
  \param sqlite handle to current DB connection
@@ -528,6 +669,8 @@ extern "C"
  \param outfile_path pathname for the GeoJSON file to be written to
  \param precision number of decimal digits for coordinates
  \param option the format to use for output
+ 
+ \sa dump_geojson_rx
 
  \note valid values for option are:
    - 0 no option
@@ -544,6 +687,34 @@ extern "C"
 					 int precision, int option);
 
 /**
+ Dumps a full geometry-table into an external GeoJSON file
+
+ \param sqlite handle to current DB connection
+ \param table the name of the table to be exported
+ \param geom_col the name of the geometry column
+ \param outfile_path pathname for the GeoJSON file to be written to
+ \param precision number of decimal digits for coordinates
+ \param option the format to use for output
+ \param rows on completion will contain the total number of exported rows
+ 
+ \sa dump_geojson
+
+ \note valid values for option are:
+   - 0 no option
+   - 1 GeoJSON MBR
+   - 2 GeoJSON Short CRS (e.g EPSG:4326)
+   - 3 MBR + Short CRS
+   - 4 GeoJSON Long CRS (e.g urn:ogc:def:crs:EPSG::4326)
+   - 5 MBR + Long CRS
+
+ \return 0 on failure, any other value on success
+ */
+    SPATIALITE_DECLARE int dump_geojson_ex (sqlite3 * sqlite, char *table,
+					    char *geom_col, char *outfile_path,
+					    int precision, int option,
+					    int *rows);
+
+/**
  Updates the LAYER_STATICS metadata table
 
  \param sqlite handle to current DB connection
diff --git a/src/headers/spatialite/gaiaexif.h b/src/headers/spatialite/gaiaexif.h
index a62f40a..71af80f 100644
--- a/src/headers/spatialite/gaiaexif.h
+++ b/src/headers/spatialite/gaiaexif.h
@@ -89,10 +89,12 @@ extern "C"
 #define GAIA_TIFF_BLOB		9
 /** this BLOB does actually contain a WebP image */
 #define GAIA_WEBP_BLOB		10
+/** this BLOB does actually contain a JP2 (Jpeg2000) image */
+#define GAIA_JP2_BLOB		11
 /** this BLOB does actually contain a SpatiaLite XmlBLOB */
-#define GAIA_XML_BLOB		11
+#define GAIA_XML_BLOB		12
 /** this BLOB does actually contain a GPKG Geometry */
-#define GAIA_GPB_BLOB		12
+#define GAIA_GPB_BLOB		13
 
 /* constants used for EXIF value types */
 /** unrecognized EXIF value */
@@ -611,7 +613,7 @@ extern "C"
  \return the BLOB type: one of GAIA_HEX_BLOB, GAIA_GIF_BLOB, GAIA_PNG_BLOB,
  GAIA_JPEG_BLOB, GAIA_EXIF_BLOB, GAIA_EXIF_GPS_BLOB, GAIA_ZIP_BLOB,
  GAIA_PDF_BLOB, GAIA_GEOMETRY_BLOB, GAIA_TIFF_BLOB, GAIA_WEBP_BLOB,
- GAIA_XML_BLOB, GAIA_GPB_BLOB
+ GAIA_JP2_BLOB, GAIA_XML_BLOB, GAIA_GPB_BLOB
  */
     GAIAEXIF_DECLARE int gaiaGuessBlobType (const unsigned char *blob,
 					    int size);
diff --git a/src/headers/spatialite/gg_formats.h b/src/headers/spatialite/gg_formats.h
index a3ebcda..1a92c37 100644
--- a/src/headers/spatialite/gg_formats.h
+++ b/src/headers/spatialite/gg_formats.h
@@ -1323,6 +1323,31 @@ extern "C"
 					   int current_row, int srid);
 
 /**
+ Reads a feature from a Shapefile object
+
+ \param shp pointer to the Shapefile object.
+ \param current_row the row number identifying the feature to be read.
+ \param srid feature's SRID 
+ \param text_dates is TRUE all DBF dates will be considered as TEXT
+
+ \return 0 on failure: any other value on success.
+
+ \sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
+ gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
+
+ \note on completion the Shapefile's \e Dbf member will contain the feature
+ read:
+ \li the \e Dbf->Geometry member will contain the corresponding Geometry
+ \li and the \e Dbf->First member will point to the linked list containing
+ the corresponding data attributes [both data formats and values].
+
+ \remark the Shapefile object should be opened in \e read mode.
+ */
+    GAIAGEO_DECLARE int gaiaReadShpEntity_ex (gaiaShapefilePtr shp,
+					      int current_row, int srid,
+					      int text_dates);
+
+/**
  Prescans a Shapefile object gathering informations
 
  \param shp pointer to the Shapefile object.
@@ -1458,6 +1483,30 @@ extern "C"
 					   int *deleted);
 
 /**
+ Reads a record from a DBF File object
+
+ \param dbf pointer to the DBF File object.
+ \param current_row the row number identifying the record to be read.
+ \param deleted on completion this variable will contain 0 if the record
+ \param text_dates is TRUE all DBF dates will be considered as TEXT
+ just read is valid: any other value if the record just read is marked as
+ \e logically \e deleted.
+
+ \return 0 on failure: any other value on success.
+
+ \sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
+ gaiaFlushDbfHeader
+
+ \note on completion the DBF File \e First member will point to the 
+ linked list containing the corresponding data attributes [both data 
+ formats and values].
+
+ \remark the DBF File object should be opened in \e read mode.
+ */
+    GAIAGEO_DECLARE int gaiaReadDbfEntity_ex (gaiaDbfPtr dbf, int current_row,
+					      int *deleted, int text_dates);
+
+/**
  Writes a record into a DBF File object
 
  \param dbf pointer to the DBF File object.
diff --git a/src/headers/spatialite/spatialite.h b/src/headers/spatialite/spatialite.h
index 963319d..37af223 100644
--- a/src/headers/spatialite/spatialite.h
+++ b/src/headers/spatialite/spatialite.h
@@ -54,6 +54,7 @@ SPATIALITE_PRIVATE int virtualbbox_extension_init (void *db,
 						   const void *p_cache);
 SPATIALITE_PRIVATE int mbrcache_extension_init (void *db);
 SPATIALITE_PRIVATE int virtual_spatialindex_extension_init (void *db);
+SPATIALITE_PRIVATE int virtual_elementary_extension_init (void *db);
 SPATIALITE_PRIVATE int virtual_xpath_extension_init (void *db,
 						     const void *p_cache);
 SPATIALITE_PRIVATE int virtualgpkg_extension_init (void *db);
diff --git a/src/headers/spatialite/sqlite.h b/src/headers/spatialite/sqlite.h
index 8301f4a..766614b 100644
--- a/src/headers/spatialite/sqlite.h
+++ b/src/headers/spatialite/sqlite.h
@@ -62,4 +62,9 @@ extern const sqlite3_api_routines *sqlite3_api;
 #endif
 #endif
 
+#ifndef SQLITE_DETERMINISTIC
+/* probably SQLite < 3.8.3 - attempting to fix */
+#define SQLITE_DETERMINISTIC	SQLITE_UTF8
+#endif
+
 #endif
diff --git a/src/headers/spatialite_private.h b/src/headers/spatialite_private.h
index 4be4aaa..4c36340 100644
--- a/src/headers/spatialite_private.h
+++ b/src/headers/spatialite_private.h
@@ -229,6 +229,8 @@ extern "C"
 	updateGeometryTriggers (void *p_sqlite, const char *table,
 				const char *column);
 
+    SPATIALITE_PRIVATE int upgradeGeometryTriggers (void *p_sqlite);
+
     SPATIALITE_PRIVATE int
 	getRealSQLnames (void *p_sqlite, const char *table, const char *column,
 			 char **real_table, char **real_column);
@@ -395,6 +397,20 @@ extern "C"
 
     SPATIALITE_PRIVATE void splite_lwgeom_semaphore_unlock (void);
 
+    SPATIALITE_PRIVATE const void *gaiaAuxClonerCreate (const void *sqlite,
+							const char *db_prefix,
+							const char *in_table,
+							const char *out_table);
+
+    SPATIALITE_PRIVATE void gaiaAuxClonerDestroy (const void *cloner);
+
+    SPATIALITE_PRIVATE void gaiaAuxClonerAddOption (const void *cloner,
+						    const char *option);
+
+    SPATIALITE_PRIVATE int gaiaAuxClonerCheckValidTarget (const void *cloner);
+
+    SPATIALITE_PRIVATE int gaiaAuxClonerExecute (const void *cloner);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/shapefiles/shapefiles.c b/src/shapefiles/shapefiles.c
index ce53e4a..63d3466 100644
--- a/src/shapefiles/shapefiles.c
+++ b/src/shapefiles/shapefiles.c
@@ -52,6 +52,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
+#include <float.h>
 
 #if defined(_WIN32) && !defined(__MINGW32__)
 #include "config-msvc.h"
@@ -384,10 +385,22 @@ load_shapefile (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
 }
 
 SPATIALITE_DECLARE int
-load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
-		   int srid, char *g_column, char *gtype, char *pk_column,
-		   int coerce2d, int compressed, int verbose, int spatial_index,
-		   int *rows, char *err_msg)
+load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table,
+		   char *charset, int srid, char *g_column, char *gtype,
+		   char *pk_column, int coerce2d, int compressed, int verbose,
+		   int spatial_index, int *rows, char *err_msg)
+{
+    return load_shapefile_ex2 (sqlite, shp_path, table, charset, srid, g_column,
+			       gtype, pk_column, coerce2d, compressed, verbose,
+			       spatial_index, 0, rows, err_msg);
+}
+
+SPATIALITE_DECLARE int
+load_shapefile_ex2 (sqlite3 * sqlite, char *shp_path, char *table,
+		    char *charset, int srid, char *g_column, char *gtype,
+		    char *pk_column, int coerce2d, int compressed,
+		    int verbose, int spatial_index, int text_dates, int *rows,
+		    char *err_msg)
 {
     sqlite3_stmt *stmt = NULL;
     int ret;
@@ -423,6 +436,8 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
     gaiaOutBuffer sql_statement;
     if (!geo_column)
 	geo_column = "Geometry";
+    if (rows)
+	*rows = -1;
     if (!xgtype)
 	;
     else
@@ -613,7 +628,10 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
 			      }
 			    break;
 			case 'D':
-			    pk_type = SQLITE_FLOAT;
+			    if (text_dates)
+				pk_type = SQLITE_TEXT;
+			    else
+				pk_type = SQLITE_FLOAT;
 			    break;
 			case 'F':
 			    pk_type = SQLITE_FLOAT;
@@ -756,7 +774,10 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
 		  }
 		break;
 	    case 'D':
-		gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
+		if (text_dates)
+		    gaiaAppendToOutBuffer (&sql_statement, "TEXT");
+		else
+		    gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
 		break;
 	    case 'F':
 		gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
@@ -1078,7 +1099,7 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
     while (1)
       {
 	  /* inserting rows from shapefile */
-	  ret = gaiaReadShpEntity (shp, current_row, srid);
+	  ret = gaiaReadShpEntity_ex (shp, current_row, srid, text_dates);
 	  if (!ret)
 	    {
 		if (!(shp->LastError))	/* normal SHP EOF */
@@ -1106,8 +1127,9 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
 		      if (pk_type == SQLITE_TEXT)
 			  sqlite3_bind_text (stmt, 1,
 					     dbf_field->Value->TxtValue,
-					     strlen (dbf_field->Value->
-						     TxtValue), SQLITE_STATIC);
+					     strlen (dbf_field->
+						     Value->TxtValue),
+					     SQLITE_STATIC);
 		      else if (pk_type == SQLITE_FLOAT)
 			  sqlite3_bind_double (stmt, 1,
 					       dbf_field->Value->DblValue);
@@ -1216,8 +1238,6 @@ load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
 		spatialite_e ("load shapefile error: <%s>\n", errMsg);
 		sqlite3_free (errMsg);
 	    }
-	  if (rows)
-	      *rows = current_row;
 	  return 0;
       }
     else
@@ -2498,11 +2518,11 @@ get_attached_view_extent_legacy (sqlite3 * handle, const char *db_prefix,
 		    (const char *) sqlite3_column_text (stmt, 0);
 		const char *geometry_column =
 		    (const char *) sqlite3_column_text (stmt, 1);
-		int count;
-		double min_x;
-		double min_y;
-		double max_x;
-		double max_y;
+		int count = 0;
+		double min_x = DBL_MAX;
+		double min_y = DBL_MAX;
+		double max_x = 0.0 - DBL_MAX;
+		double max_y = 0.0 - DBL_MAX;
 		if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
 		    is_null = 1;
 		else
@@ -2621,6 +2641,8 @@ dump_shapefile (sqlite3 * sqlite, char *table, char *column, char *shp_path,
     char *xxtable;
     struct auxdbf_list *auxdbf = NULL;
 
+    if (xrows)
+	*xrows = -1;
     if (geom_type)
       {
 	  /* normalizing required geometry type */
@@ -2934,7 +2956,7 @@ dump_shapefile (sqlite3 * sqlite, char *table, char *column, char *shp_path,
 	  if (fld->TextValuesCount > 0)
 	    {
 		sql_type = SQLITE_TEXT;
-		max_len = 255;
+		max_len = 254;
 		if (fld->MaxSize)
 		    max_len = fld->MaxSize->MaxSize;
 	    }
@@ -2949,6 +2971,11 @@ dump_shapefile (sqlite3 * sqlite, char *table, char *column, char *shp_path,
 	    {
 		if (max_len == 0)	/* avoiding ZERO-length fields */
 		    max_len = 1;
+		if (max_len > 254)
+		  {
+		      /* DBF C: max allowed lenght */
+		      max_len = 254;
+		  }
 		gaiaAddDbfField (dbf_list, fld->AttributeFieldName, 'C', offset,
 				 max_len, 0);
 		offset += max_len;
@@ -3052,8 +3079,8 @@ dump_shapefile (sqlite3 * sqlite, char *table, char *column, char *shp_path,
 				      SQLITE_TEXT)
 				    {
 					dummy =
-					    (char *)
-					    sqlite3_column_text (stmt, i);
+					    (char *) sqlite3_column_text (stmt,
+									  i);
 					gaiaSetStrValue (dbf_field, dummy);
 				    }
 				  else if (sqlite3_column_type (stmt, i) ==
@@ -3162,6 +3189,15 @@ SPATIALITE_DECLARE int
 load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 	     char *charset, int verbose, int *rows, char *err_msg)
 {
+    return load_dbf_ex2 (sqlite, dbf_path, table, pk_column, charset, verbose,
+			 0, rows, err_msg);
+}
+
+SPATIALITE_DECLARE int
+load_dbf_ex2 (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
+	      char *charset, int verbose, int text_dates, int *rows,
+	      char *err_msg)
+{
     sqlite3_stmt *stmt;
     int ret;
     char *errMsg = NULL;
@@ -3189,6 +3225,8 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
     int pk_type = SQLITE_INTEGER;
     int pk_set;
     qtable = gaiaDoubleQuotedSql (table);
+    if (rows)
+	*rows = -1;
 /* checking if TABLE already exists */
     sql = sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE "
 			   "type = 'table' AND Lower(name) = Lower(%Q)", table);
@@ -3303,7 +3341,10 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 			      }
 			    break;
 			case 'D':
-			    pk_type = SQLITE_FLOAT;
+			    if (text_dates)
+				pk_type = SQLITE_TEXT;
+			    else
+				pk_type = SQLITE_FLOAT;
 			    break;
 			case 'F':
 			    pk_type = SQLITE_FLOAT;
@@ -3437,7 +3478,10 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 		  }
 		break;
 	    case 'D':
-		gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
+		if (text_dates)
+		    gaiaAppendToOutBuffer (&sql_statement, " TEXT");
+		else
+		    gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
 		break;
 	    case 'F':
 		gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
@@ -3527,7 +3571,7 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
     while (1)
       {
 	  /* inserting rows from DBF */
-	  ret = gaiaReadDbfEntity (dbf, current_row, &deleted);
+	  ret = gaiaReadDbfEntity_ex (dbf, current_row, &deleted, text_dates);
 	  if (!ret)
 	    {
 		if (!(dbf->LastError))	/* normal DBF EOF */
@@ -3559,8 +3603,9 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 		      if (pk_type == SQLITE_TEXT)
 			  sqlite3_bind_text (stmt, 1,
 					     dbf_field->Value->TxtValue,
-					     strlen (dbf_field->Value->
-						     TxtValue), SQLITE_STATIC);
+					     strlen (dbf_field->
+						     Value->TxtValue),
+					     SQLITE_STATIC);
 		      else if (pk_type == SQLITE_FLOAT)
 			  sqlite3_bind_double (stmt, 1,
 					       dbf_field->Value->DblValue);
@@ -3654,8 +3699,6 @@ load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 		spatialite_e ("load DBF error: <%s>\n", errMsg);
 		sqlite3_free (errMsg);
 	    };
-	  if (rows)
-	      *rows = current_row;
 	  if (qtable)
 	      free (qtable);
 	  if (qpk_name)
@@ -3690,6 +3733,14 @@ SPATIALITE_DECLARE int
 dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
 	  char *err_msg)
 {
+    int rows;
+    return dump_dbf_ex (sqlite, table, dbf_path, charset, &rows, err_msg);
+}
+
+SPATIALITE_DECLARE int
+dump_dbf_ex (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
+	     int *xrows, char *err_msg)
+{
 /* DBF dump */
     int rows;
     int i;
@@ -3715,6 +3766,7 @@ dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
     char *table_name = NULL;
     struct auxdbf_list *auxdbf = NULL;
 
+    *xrows = -1;
     shp_parse_table_name (table, &db_prefix, &table_name);
 /*
 / preparing SQL statement 
@@ -3778,6 +3830,11 @@ dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
 		      if (type == SQLITE_TEXT)
 			{
 			    len = sqlite3_column_bytes (stmt, i);
+			    if (len > 254)
+			      {
+				  /* DBF C type: max allowed length */
+				  len = 254;
+			      }
 			    sql_type[i] = SQLITE_TEXT;
 			    if (len > max_length[i])
 				max_length[i] = len;
@@ -3895,8 +3952,9 @@ dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
 				  if (sqlite3_column_type (stmt, i) ==
 				      SQLITE_TEXT)
 				    {
-					dummy = (char *)
-					    sqlite3_column_text (stmt, i);
+					dummy =
+					    (char *) sqlite3_column_text (stmt,
+									  i);
 					gaiaSetStrValue (dbf_field, dummy);
 				    }
 				  else if (sqlite3_column_type (stmt, i) ==
@@ -3945,6 +4003,7 @@ dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
 	free (db_prefix);
     if (table_name != NULL)
 	free (table_name);
+    *xrows = rows;
     return 1;
   sql_error:
 /* some SQL error occurred */
@@ -4058,6 +4117,15 @@ SPATIALITE_DECLARE int
 dump_kml (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
 	  char *name_col, char *desc_col, int precision)
 {
+    int rows;
+    return dump_kml_ex (sqlite, table, geom_col, kml_path, name_col, desc_col,
+			precision, &rows);
+}
+
+SPATIALITE_DECLARE int
+dump_kml_ex (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
+	     char *name_col, char *desc_col, int precision, int *xrows)
+{
 /* dumping a  geometry table as KML */
     char *sql;
     char *xname;
@@ -4070,6 +4138,7 @@ dump_kml (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
     int rows = 0;
     int is_const = 1;
 
+    *xrows = -1;
 /* opening/creating the KML file */
     out = fopen (kml_path, "wb");
     if (!out)
@@ -4152,6 +4221,7 @@ dump_kml (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
     fprintf (out, "</kml>\r\n");
     sqlite3_finalize (stmt);
     fclose (out);
+    *xrows = rows;
     return 1;
 
   sql_error:
@@ -4235,6 +4305,7 @@ check_duplicated_rows (sqlite3 * sqlite, char *table, int *dupl_count)
     if (is_table (sqlite, table) == 0)
       {
 	  spatialite_e (".chkdupl %s: no such table\n", table);
+	  *dupl_count = -1;
 	  return;
       }
 /* extracting the column names (excluding any Primary Key) */
@@ -4477,6 +4548,8 @@ remove_duplicated_rows_ex (sqlite3 * sqlite, char *table, int *removed)
     if (is_table (sqlite, table) == 0)
       {
 	  spatialite_e (".remdupl %s: no such table\n", table);
+	  if (removed != NULL)
+	      *removed = -1;
 	  return;
       }
 /* extracting the column names (excluding any Primary Key) */
@@ -5078,6 +5151,17 @@ elementary_geometries (sqlite3 * sqlite,
 		       char *pKey, char *multiId)
 {
 /* attempting to create a derived table surely containing elemetary Geoms */
+    int rows;
+    elementary_geometries_ex (sqlite, inTable, geometry, outTable, pKey,
+			      multiId, &rows);
+}
+
+SPATIALITE_DECLARE void
+elementary_geometries_ex (sqlite3 * sqlite,
+			  char *inTable, char *geometry, char *outTable,
+			  char *pKey, char *multiId, int *xrows)
+{
+/* attempting to create a derived table surely containing elemetary Geoms */
     char type[128];
     int srid;
     char dims[64];
@@ -5102,12 +5186,14 @@ elementary_geometries (sqlite3 * sqlite,
     sqlite3_stmt *stmt_out = NULL;
     int n_columns;
     sqlite3_int64 id = 0;
+    int inserted = 0;
 
     if (check_elementary
 	(sqlite, inTable, geometry, outTable, pKey, multiId, type, &srid,
 	 dims) == 0)
       {
 	  spatialite_e (".elemgeo: invalid args\n");
+	  *xrows = 0;
 	  return;
       }
 
@@ -5332,6 +5418,7 @@ elementary_geometries (sqlite3 * sqlite,
 					  sqlite3_errmsg (sqlite));
 			    goto abort;
 			}
+		      inserted++;
 		  }
 		else
 		  {
@@ -5411,6 +5498,7 @@ elementary_geometries (sqlite3 * sqlite,
 						sqlite3_errmsg (sqlite));
 				  goto abort;
 			      }
+			    inserted++;
 			    pt = pt->Next;
 			}
 		      ln = g->FirstLinestring;
@@ -5484,6 +5572,7 @@ elementary_geometries (sqlite3 * sqlite,
 						sqlite3_errmsg (sqlite));
 				  goto abort;
 			      }
+			    inserted++;
 			    ln = ln->Next;
 			}
 		      pg = g->FirstPolygon;
@@ -5557,6 +5646,7 @@ elementary_geometries (sqlite3 * sqlite,
 						sqlite3_errmsg (sqlite));
 				  goto abort;
 			      }
+			    inserted++;
 			    pg = pg->Next;
 			}
 		      gaiaFreeGeomColl (g);
@@ -5580,6 +5670,7 @@ elementary_geometries (sqlite3 * sqlite,
 	  sqlite3_free (errMsg);
 	  goto abort;
       }
+    *xrows = inserted;
     return;
 
   abort:
@@ -5587,6 +5678,7 @@ elementary_geometries (sqlite3 * sqlite,
 	sqlite3_finalize (stmt_in);
     if (stmt_out)
 	sqlite3_finalize (stmt_out);
+    *xrows = 0;
 }
 
 #ifndef OMIT_FREEXL		/* including FreeXL */
@@ -5613,6 +5705,8 @@ load_XL (sqlite3 * sqlite, const char *path, const char *table,
     gaiaOutBuffer sql_statement;
     FreeXL_CellValue cell;
     int already_exists = 0;
+
+    *rows = 0;
 /* checking if TABLE already exists */
     sql =
 	sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE type = 'table' "
@@ -5715,8 +5809,8 @@ load_XL (sqlite3 * sqlite, const char *path, const char *table,
 						     cell.value.int_value);
 			    else if (cell.type == FREEXL_CELL_DOUBLE)
 				dummy = sqlite3_mprintf ("%1.2f ",
-							 cell.value.
-							 double_value);
+							 cell.
+							 value.double_value);
 			    else if (cell.type == FREEXL_CELL_TEXT
 				     || cell.type == FREEXL_CELL_SST_TEXT
 				     || cell.type == FREEXL_CELL_DATE
@@ -5727,8 +5821,8 @@ load_XL (sqlite3 * sqlite, const char *path, const char *table,
 				  if (len < 256)
 				      dummy =
 					  sqlite3_mprintf ("%s",
-							   cell.value.
-							   text_value);
+							   cell.
+							   value.text_value);
 				  else
 				      dummy = sqlite3_mprintf ("col_%d", col);
 			      }
@@ -5945,16 +6039,27 @@ load_XL (sqlite3 * sqlite, const char *path, const char *table,
 	spatialite_e ("XL datasource '%s' is not valid\n", path);
     else
 	sprintf (err_msg, "XL datasource '%s' is not valid\n", path);
+    *rows = 0;
     return 0;
 }
 
 #endif /* FreeXL enabled/disabled */
 
 SPATIALITE_DECLARE int
-dump_geojson (sqlite3 * sqlite, char *table, char *geom_col, char *outfile_path,
-	      int precision, int option)
+dump_geojson (sqlite3 * sqlite, char *table, char *geom_col,
+	      char *outfile_path, int precision, int option)
+{
+    int rows;
+    return dump_geojson_ex (sqlite, table, geom_col, outfile_path, precision,
+			    option, &rows);
+}
+
+SPATIALITE_DECLARE int
+dump_geojson_ex (sqlite3 * sqlite, char *table, char *geom_col,
+		 char *outfile_path, int precision, int option, int *xrows)
 {
 /* dumping a  geometry table as GeoJSON - Brad Hards 2011-11-09 */
+/* sandro furieri 2014-08-30: adding the "int *xrows" argument */
     char *sql;
     char *xgeom_col;
     char *xtable;
@@ -5963,6 +6068,7 @@ dump_geojson (sqlite3 * sqlite, char *table, char *geom_col, char *outfile_path,
     int ret;
     int rows = 0;
 
+    *xrows = -1;
 /* opening/creating the GeoJSON output file */
     out = fopen (outfile_path, "wb");
     if (!out)
@@ -6007,6 +6113,7 @@ dump_geojson (sqlite3 * sqlite, char *table, char *geom_col, char *outfile_path,
 
     sqlite3_finalize (stmt);
     fclose (out);
+    *xrows = rows;
     return 1;
 
   sql_error:
diff --git a/src/spatialite/Makefile.am b/src/spatialite/Makefile.am
index a87ad04..be4acdb 100644
--- a/src/spatialite/Makefile.am
+++ b/src/spatialite/Makefile.am
@@ -10,6 +10,7 @@ SPATIALITE_COMMON_SOURCES = mbrcache.c \
 	metatables.c \
 	statistics.c \
 	extra_tables.c \
+	table_cloner.c \
 	virtualdbf.c \
 	virtualXL.c \
 	virtualfdo.c \
@@ -18,7 +19,8 @@ SPATIALITE_COMMON_SOURCES = mbrcache.c \
 	virtualspatialindex.c \
 	virtualnetwork.c \
 	virtualshape.c \
-	virtualxpath.c
+	virtualxpath.c \
+	virtualelementary.c
 
 libsplite_la_SOURCES = $(SPATIALITE_COMMON_SOURCES)
 
diff --git a/src/spatialite/Makefile.in b/src/spatialite/Makefile.in
index 7db32bd..c10fb3e 100644
--- a/src/spatialite/Makefile.in
+++ b/src/spatialite/Makefile.in
@@ -97,12 +97,12 @@ libsplite_la_LIBADD =
 am__objects_1 = libsplite_la-mbrcache.lo libsplite_la-spatialite.lo \
 	libsplite_la-spatialite_init.lo libsplite_la-metatables.lo \
 	libsplite_la-statistics.lo libsplite_la-extra_tables.lo \
-	libsplite_la-virtualdbf.lo libsplite_la-virtualXL.lo \
-	libsplite_la-virtualfdo.lo libsplite_la-virtualgpkg.lo \
-	libsplite_la-virtualbbox.lo \
+	libsplite_la-table_cloner.lo libsplite_la-virtualdbf.lo \
+	libsplite_la-virtualXL.lo libsplite_la-virtualfdo.lo \
+	libsplite_la-virtualgpkg.lo libsplite_la-virtualbbox.lo \
 	libsplite_la-virtualspatialindex.lo \
 	libsplite_la-virtualnetwork.lo libsplite_la-virtualshape.lo \
-	libsplite_la-virtualxpath.lo
+	libsplite_la-virtualxpath.lo libsplite_la-virtualelementary.lo
 am_libsplite_la_OBJECTS = $(am__objects_1)
 libsplite_la_OBJECTS = $(am_libsplite_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
@@ -116,11 +116,12 @@ splite_la_LIBADD =
 am__objects_2 = splite_la-mbrcache.lo splite_la-spatialite.lo \
 	splite_la-spatialite_init.lo splite_la-metatables.lo \
 	splite_la-statistics.lo splite_la-extra_tables.lo \
-	splite_la-virtualdbf.lo splite_la-virtualXL.lo \
-	splite_la-virtualfdo.lo splite_la-virtualgpkg.lo \
-	splite_la-virtualbbox.lo splite_la-virtualspatialindex.lo \
-	splite_la-virtualnetwork.lo splite_la-virtualshape.lo \
-	splite_la-virtualxpath.lo
+	splite_la-table_cloner.lo splite_la-virtualdbf.lo \
+	splite_la-virtualXL.lo splite_la-virtualfdo.lo \
+	splite_la-virtualgpkg.lo splite_la-virtualbbox.lo \
+	splite_la-virtualspatialindex.lo splite_la-virtualnetwork.lo \
+	splite_la-virtualshape.lo splite_la-virtualxpath.lo \
+	splite_la-virtualelementary.lo
 am_splite_la_OBJECTS = $(am__objects_2)
 splite_la_OBJECTS = $(am_splite_la_OBJECTS)
 splite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@@ -325,6 +326,7 @@ SPATIALITE_COMMON_SOURCES = mbrcache.c \
 	metatables.c \
 	statistics.c \
 	extra_tables.c \
+	table_cloner.c \
 	virtualdbf.c \
 	virtualXL.c \
 	virtualfdo.c \
@@ -333,7 +335,8 @@ SPATIALITE_COMMON_SOURCES = mbrcache.c \
 	virtualspatialindex.c \
 	virtualnetwork.c \
 	virtualshape.c \
-	virtualxpath.c
+	virtualxpath.c \
+	virtualelementary.c
 
 libsplite_la_SOURCES = $(SPATIALITE_COMMON_SOURCES)
 libsplite_la_CFLAGS = -fvisibility=hidden
@@ -408,9 +411,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-spatialite.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-spatialite_init.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-statistics.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-table_cloner.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualXL.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualbbox.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualdbf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualelementary.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualfdo.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualgpkg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libsplite_la-virtualnetwork.Plo at am__quote@
@@ -423,9 +428,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-spatialite.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-spatialite_init.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-statistics.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-table_cloner.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualXL.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualbbox.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualdbf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualelementary.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualfdo.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualgpkg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/splite_la-virtualnetwork.Plo at am__quote@
@@ -496,6 +503,13 @@ libsplite_la-extra_tables.lo: extra_tables.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -c -o libsplite_la-extra_tables.lo `test -f 'extra_tables.c' || echo '$(srcdir)/'`extra_tables.c
 
+libsplite_la-table_cloner.lo: table_cloner.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -MT libsplite_la-table_cloner.lo -MD -MP -MF $(DEPDIR)/libsplite_la-table_cloner.Tpo -c -o libsplite_la-table_cloner.lo `test -f 'table_cloner.c' || echo '$(srcdir)/'`table_cloner.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libsplite_la-table_cloner.Tpo $(DEPDIR)/libsplite_la-table_cloner.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table_cloner.c' object='libsplite_la-table_cloner.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -c -o libsplite_la-table_cloner.lo `test -f 'table_cloner.c' || echo '$(srcdir)/'`table_cloner.c
+
 libsplite_la-virtualdbf.lo: virtualdbf.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -MT libsplite_la-virtualdbf.lo -MD -MP -MF $(DEPDIR)/libsplite_la-virtualdbf.Tpo -c -o libsplite_la-virtualdbf.lo `test -f 'virtualdbf.c' || echo '$(srcdir)/'`virtualdbf.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libsplite_la-virtualdbf.Tpo $(DEPDIR)/libsplite_la-virtualdbf.Plo
@@ -559,6 +573,13 @@ libsplite_la-virtualxpath.lo: virtualxpath.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -c -o libsplite_la-virtualxpath.lo `test -f 'virtualxpath.c' || echo '$(srcdir)/'`virtualxpath.c
 
+libsplite_la-virtualelementary.lo: virtualelementary.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -MT libsplite_la-virtualelementary.lo -MD -MP -MF $(DEPDIR)/libsplite_la-virtualelementary.Tpo -c -o libsplite_la-virtualelementary.lo `test -f 'virtualelementary.c' || echo '$(srcdir)/'`virtualelementary.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libsplite_la-virtualelementary.Tpo $(DEPDIR)/libsplite_la-virtualelementary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='virtualelementary.c' object='libsplite_la-virtualelementary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsplite_la_CFLAGS) $(CFLAGS) -c -o libsplite_la-virtualelementary.lo `test -f 'virtualelementary.c' || echo '$(srcdir)/'`virtualelementary.c
+
 splite_la-mbrcache.lo: mbrcache.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT splite_la-mbrcache.lo -MD -MP -MF $(DEPDIR)/splite_la-mbrcache.Tpo -c -o splite_la-mbrcache.lo `test -f 'mbrcache.c' || echo '$(srcdir)/'`mbrcache.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/splite_la-mbrcache.Tpo $(DEPDIR)/splite_la-mbrcache.Plo
@@ -601,6 +622,13 @@ splite_la-extra_tables.lo: extra_tables.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o splite_la-extra_tables.lo `test -f 'extra_tables.c' || echo '$(srcdir)/'`extra_tables.c
 
+splite_la-table_cloner.lo: table_cloner.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT splite_la-table_cloner.lo -MD -MP -MF $(DEPDIR)/splite_la-table_cloner.Tpo -c -o splite_la-table_cloner.lo `test -f 'table_cloner.c' || echo '$(srcdir)/'`table_cloner.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/splite_la-table_cloner.Tpo $(DEPDIR)/splite_la-table_cloner.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table_cloner.c' object='splite_la-table_cloner.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o splite_la-table_cloner.lo `test -f 'table_cloner.c' || echo '$(srcdir)/'`table_cloner.c
+
 splite_la-virtualdbf.lo: virtualdbf.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT splite_la-virtualdbf.lo -MD -MP -MF $(DEPDIR)/splite_la-virtualdbf.Tpo -c -o splite_la-virtualdbf.lo `test -f 'virtualdbf.c' || echo '$(srcdir)/'`virtualdbf.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/splite_la-virtualdbf.Tpo $(DEPDIR)/splite_la-virtualdbf.Plo
@@ -664,6 +692,13 @@ splite_la-virtualxpath.lo: virtualxpath.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o splite_la-virtualxpath.lo `test -f 'virtualxpath.c' || echo '$(srcdir)/'`virtualxpath.c
 
+splite_la-virtualelementary.lo: virtualelementary.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT splite_la-virtualelementary.lo -MD -MP -MF $(DEPDIR)/splite_la-virtualelementary.Tpo -c -o splite_la-virtualelementary.lo `test -f 'virtualelementary.c' || echo '$(srcdir)/'`virtualelementary.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/splite_la-virtualelementary.Tpo $(DEPDIR)/splite_la-virtualelementary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='virtualelementary.c' object='splite_la-virtualelementary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(splite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(splite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o splite_la-virtualelementary.lo `test -f 'virtualelementary.c' || echo '$(srcdir)/'`virtualelementary.c
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/src/spatialite/extra_tables.c b/src/spatialite/extra_tables.c
index f2e1dad..80bf694 100644
--- a/src/spatialite/extra_tables.c
+++ b/src/spatialite/extra_tables.c
@@ -830,6 +830,11 @@ create_raster_coverages (sqlite3 * sqlite)
 	"extent_miny DOUBLE,\n"
 	"extent_maxx DOUBLE,\n"
 	"extent_maxy DOUBLE,\n"
+	"strict_resolution INTEGER NOT NULL,\n"
+	"mixed_resolutions INTEGER NOT NULL,\n"
+	"section_paths INTEGER NOT NULL,\n"
+	"section_md5 INTEGER NOT NULL,\n"
+	"section_summary INTEGER NOT NULL,\n"
 	"CONSTRAINT fk_rc_srs FOREIGN KEY (srid) "
 	"REFERENCES spatial_ref_sys (srid))";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
@@ -845,7 +850,7 @@ create_raster_coverages (sqlite3 * sqlite)
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"coverage_name value must not contain a single quote')\n"
 	"WHERE NEW.coverage_name LIKE ('%''%');\n"
-	"SELECT RAISE(ABORT,'insert on raster_coverages_layers violates constraint: "
+	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"coverage_name value must not contain a double quote')\n"
 	"WHERE NEW.coverage_name LIKE ('%\"%');\n"
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
@@ -966,9 +971,10 @@ create_raster_coverages (sqlite3 * sqlite)
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"compression must be one of ''NONE'' | ''DEFLATE'' | ''LZMA'' | "
 	"''PNG'' | ''JPEG'' | ''LOSSY_WEBP'' | ''LOSSLESS_WEBP'' | "
-	"''CCITTFAX4''')\n"
+	"''CCITTFAX4'' | ''CHARLS'' | ''LOSSY_JP2'' | ''LOSSLESS_JP2''')\n"
 	"WHERE NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
-	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', " "'CCITTFAX4');\nEND";
+	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'CCITTFAX4', "
+	"'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2');\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -982,9 +988,10 @@ create_raster_coverages (sqlite3 * sqlite)
 	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
 	"compression must be one of ''NONE'' | ''DEFLATE'' | ''LZMA'' | "
 	"''PNG'' | ''JPEG'' | ''LOSSY_WEBP'' | ''LOSSLESS_WEBP'' | "
-	"''CCITTFAX4''')\n"
+	"''CCITTFAX4'' | ''CHARLS'' | ''LOSSY_JP2'' | ''LOSSLESS_JP2''')\n"
 	"WHERE NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
-	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', " "'CCITTFAX4');\nEND";
+	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'CCITTFAX4', "
+	"'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2');\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1397,9 +1404,10 @@ create_raster_coverages (sqlite3 * sqlite)
     sql = "CREATE TRIGGER raster_coverages_graycompr_insert\n"
 	"BEFORE INSERT ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
-	"inconsistent GRAYSCALE compression')\nWHERE NEW.pixel_type = 'GRAYSCALE' "
-	"AND NEW.compression NOT IN ('NONE', 'PNG', 'JPEG', 'LOSSY_WEBP', "
-	"'LOSSLESS_WEBP');\nEND";
+	"inconsistent GRAYSCALE compression')\nWHERE NEW.pixel_type = "
+	"'GRAYSCALE' AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
+	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2');\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1410,9 +1418,10 @@ create_raster_coverages (sqlite3 * sqlite)
     sql = "CREATE TRIGGER raster_coverages_graycompr_update\n"
 	"BEFORE UPDATE ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
-	"inconsistent GRAYSCALE compression')\nWHERE NEW.pixel_type = 'GRAYSCALE' "
-	"AND NEW.compression NOT IN ('NONE', 'PNG', 'JPEG', 'LOSSY_WEBP', "
-	"'LOSSLESS_WEBP');\nEND";
+	"inconsistent GRAYSCALE compression')\nWHERE NEW.pixel_type = "
+	"'GRAYSCALE' AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
+	"'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2');\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1449,9 +1458,11 @@ create_raster_coverages (sqlite3 * sqlite)
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"inconsistent RGB compression')\nWHERE NEW.pixel_type = 'RGB' "
 	"AND ((NEW.sample_type = 'UINT8' AND NEW.compression NOT IN ("
-	"'NONE', 'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP') OR "
-	"(NEW.sample_type = 'UINT16' AND NEW.compression NOT IN ("
-	"'NONE', 'DEFLATE', 'LZMA'))));\nEND";
+	"'NONE', 'DEFLATE', 'LZMA', 'PNG', 'JPEG', 'LOSSY_WEBP', "
+	"'LOSSLESS_WEBP', 'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2') OR "
+	"(NEW.sample_type = 'UINT16' AND NEW.compression NOT IN "
+	"('NONE', 'DEFLATE', 'LZMA', 'PNG', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2'))));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1464,9 +1475,11 @@ create_raster_coverages (sqlite3 * sqlite)
 	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
 	"inconsistent RGB compression')\nWHERE NEW.pixel_type = 'RGB' "
 	"AND ((NEW.sample_type = 'UINT8' AND NEW.compression NOT IN ("
-	"'NONE', 'PNG', 'JPEG', 'LOSSY_WEBP', 'LOSSLESS_WEBP') OR "
-	"(NEW.sample_type = 'UINT16' AND NEW.compression NOT IN ("
-	"'NONE', 'DEFLATE', 'LZMA'))));\nEND";
+	"'NONE', 'DEFLATE', 'LZMA', 'PNG', 'JPEG', 'LOSSY_WEBP', "
+	"'LOSSLESS_WEBP', 'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2') OR "
+	"(NEW.sample_type = 'UINT16' AND NEW.compression NOT IN "
+	"('NONE', 'DEFLATE', 'LZMA', 'PNG', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2'))));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1525,8 +1538,16 @@ create_raster_coverages (sqlite3 * sqlite)
     sql = "CREATE TRIGGER raster_coverages_multicompr_insert\n"
 	"BEFORE INSERT ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
-	"inconsistent MULTIBAND compression')\nWHERE NEW.pixel_type = 'MULTIBAND' "
-	"AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA');\nEND";
+	"inconsistent MULTIBAND compression')\nWHERE NEW.pixel_type = "
+	"'MULTIBAND' AND ((NEW.num_bands NOT IN (3, 4) AND "
+	"NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA')) OR	"
+	"(NEW.sample_type <> 'UINT16' AND NEW.num_bands IN (3, 4) AND "
+	"NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', 'PNG', "
+	"'CHARLS', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2')) OR (NEW.sample_type = 'UINT16' AND "
+	"NEW.num_bands IN (3, 4) AND NEW.compression NOT IN "
+	"('NONE', 'DEFLATE', 'LZMA', 'PNG', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2')));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1534,11 +1555,19 @@ create_raster_coverages (sqlite3 * sqlite)
 	  sqlite3_free (err_msg);
 	  return 0;
       }
-    sql = "CREATE TRIGGER raster_coverages_multibands_insert\n"
-	"BEFORE INSERT ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
-	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
-	"inconsistent MULTIBAND num_bands')\nWHERE NEW.pixel_type = 'MULTIBAND' "
-	"AND NEW.num_bands < 2;\nEND";
+    sql = "CREATE TRIGGER raster_coverages_multicompr_update\n"
+	"BEFORE UPDATE ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
+	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
+	"inconsistent MULTIBAND compression')\nWHERE NEW.pixel_type = "
+	"'MULTIBAND' AND ((NEW.num_bands NOT IN (3, 4) AND "
+	"NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA')) OR	"
+	"(NEW.sample_type <> 'UINT16' AND NEW.num_bands IN (3, 4) AND "
+	"NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', 'PNG', "
+	"'CHARLS', 'LOSSY_WEBP', 'LOSSLESS_WEBP', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2')) OR (NEW.sample_type = 'UINT16' AND "
+	"NEW.num_bands IN (3, 4) AND NEW.compression NOT IN "
+	"('NONE', 'DEFLATE', 'LZMA', 'PNG', 'CHARLS', 'LOSSY_JP2', "
+	"'LOSSLESS_JP2')));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1546,9 +1575,9 @@ create_raster_coverages (sqlite3 * sqlite)
 	  sqlite3_free (err_msg);
 	  return 0;
       }
-    sql = "CREATE TRIGGER raster_coverages_multibands_update\n"
-	"BEFORE UPDATE ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
-	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
+    sql = "CREATE TRIGGER raster_coverages_multibands_insert\n"
+	"BEFORE INSERT ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
+	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"inconsistent MULTIBAND num_bands')\nWHERE NEW.pixel_type = 'MULTIBAND' "
 	"AND NEW.num_bands < 2;\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
@@ -1558,11 +1587,11 @@ create_raster_coverages (sqlite3 * sqlite)
 	  sqlite3_free (err_msg);
 	  return 0;
       }
-    sql = "CREATE TRIGGER raster_coverages_multicompr_update\n"
+    sql = "CREATE TRIGGER raster_coverages_multibands_update\n"
 	"BEFORE UPDATE ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
-	"inconsistent MULTIBAND compression')\nWHERE NEW.pixel_type = 'MULTIBAND' "
-	"AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA');\nEND";
+	"inconsistent MULTIBAND num_bands')\nWHERE NEW.pixel_type = 'MULTIBAND' "
+	"AND NEW.num_bands < 2;\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1600,7 +1629,10 @@ create_raster_coverages (sqlite3 * sqlite)
 	"BEFORE INSERT ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT,'insert on raster_coverages violates constraint: "
 	"inconsistent DATAGRID compression')\nWHERE NEW.pixel_type = 'DATAGRID' "
-	"AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA');\nEND";
+	"AND (((NEW.sample_type NOT IN ('UINT8', 'UINT16')) AND NEW.compression "
+	"NOT IN ('NONE', 'DEFLATE', 'LZMA')) OR ((NEW.sample_type IN ('UINT8', "
+	"'UINT16')) AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
+	"'PNG', 'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2')));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1612,7 +1644,10 @@ create_raster_coverages (sqlite3 * sqlite)
 	"BEFORE UPDATE ON 'raster_coverages'\nFOR EACH ROW BEGIN\n"
 	"SELECT RAISE(ABORT, 'update on raster_coverages violates constraint: "
 	"inconsistent DATAGRID compression')\nWHERE NEW.pixel_type = 'DATAGRID' "
-	"AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA');\nEND";
+	"AND (((NEW.sample_type NOT IN ('UINT8', 'UINT16')) AND NEW.compression "
+	"NOT IN ('NONE', 'DEFLATE', 'LZMA')) OR ((NEW.sample_type IN ('UINT8', "
+	"'UINT16')) AND NEW.compression NOT IN ('NONE', 'DEFLATE', 'LZMA', "
+	"'PNG', 'CHARLS', 'LOSSY_JP2', 'LOSSLESS_JP2')));\nEND";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
@@ -1715,7 +1750,11 @@ create_raster_coverages (sqlite3 * sqlite)
 	"c.extent_miny AS extent_miny, c.extent_maxx AS extent_maxx, "
 	"c.extent_maxy AS extent_maxy, c.srid AS srid, "
 	"s.auth_name AS auth_name, s.auth_srid AS auth_srid, "
-	"s.ref_sys_name AS ref_sys_name, s.proj4text AS proj4text\n"
+	"s.ref_sys_name AS ref_sys_name, s.proj4text AS proj4text, "
+	"c.strict_resolution AS strict_resolution, "
+	"c.mixed_resolutions AS mixed_resolutions, "
+	"c.section_paths AS section_paths, c.section_md5 AS section_md5, "
+	"c.section_summary AS section_summary\n"
 	"FROM raster_coverages AS c\n"
 	"LEFT JOIN spatial_ref_sys AS s ON (c.srid = s.srid)";
     ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
diff --git a/src/spatialite/metatables.c b/src/spatialite/metatables.c
index 1908b0f..2ac2aaf 100644
--- a/src/spatialite/metatables.c
+++ b/src/spatialite/metatables.c
@@ -2778,6 +2778,56 @@ createGeometryColumns (void *p_sqlite)
     return 1;
 }
 
+SPATIALITE_PRIVATE int
+upgradeGeometryTriggers (void *p_sqlite)
+{
+/* upgrading all triggers for any Spatial Column */
+    sqlite3 *sqlite = (sqlite3 *) p_sqlite;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    char *sql_statement;
+    int retcode;
+    int metadata_version = checkSpatialMetaData (sqlite);
+    if (metadata_version < 3)
+    return 0;
+
+	  sql_statement =
+	      sqlite3_mprintf ("SELECT f_table_name, f_geometry_column "
+			       "FROM geometry_columns");
+/* compiling SQL prepared statement */
+    ret =
+	sqlite3_prepare_v2 (sqlite, sql_statement, strlen (sql_statement),
+			    &stmt, NULL);
+    sqlite3_free (sql_statement);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("upgradeGeometryTriggers: error %d \"%s\"\n",
+			sqlite3_errcode (sqlite), sqlite3_errmsg (sqlite));
+	  return 0;
+      }
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *table = (const char *)sqlite3_column_text (stmt, 0);
+		const char *column = (const char *)sqlite3_column_text (stmt, 1);
+		updateGeometryTriggers (sqlite, table, column);
+		retcode = 1;
+	    }
+	  else
+	    {
+		retcode = 0;
+		break;
+	    }
+      }
+    ret = sqlite3_finalize (stmt);
+    return retcode;
+}
+
 SPATIALITE_PRIVATE void
 updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 {
@@ -2789,7 +2839,7 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
     int index;
     int cached;
     int dims;
-    char *txt_dims;
+    char *txt_dims = NULL;
     int len;
     char *errMsg = NULL;
     char *sql_statement;
@@ -3015,15 +3065,15 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 		      /* current metadata style >= v.4.0.0 */
 		      sql_statement =
 			  sqlite3_mprintf
-			  ("CREATE TRIGGER \"%s\" BEFORE UPDATE ON \"%s\"\n"
+			  ("CREATE TRIGGER \"%s\" BEFORE UPDATE OF \"%s\" ON \"%s\"\n"
 			   "FOR EACH ROW BEGIN\n"
 			   "SELECT RAISE(ROLLBACK, '%q.%q violates Geometry constraint [geom-type or SRID not allowed]')\n"
 			   "WHERE (SELECT geometry_type FROM geometry_columns\n"
 			   "WHERE Lower(f_table_name) = Lower(%Q) AND "
 			   "Lower(f_geometry_column) = Lower(%Q)\n"
 			   "AND GeometryConstraints(NEW.\"%s\", geometry_type, srid) = 1) IS NULL;\nEND",
-			   quoted_trigger, quoted_table, p_table, p_column,
-			   p_table, p_column, quoted_column);
+			   quoted_trigger, quoted_column, quoted_table, p_table,
+			   p_column, p_table, p_column, quoted_column);
 		      free (quoted_trigger);
 		      free (quoted_table);
 		      free (quoted_column);
@@ -3126,88 +3176,75 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 			  goto error;
 		  }
 
-		if (index == 0 && cached == 0)
+		if (metadata_version == 3)
 		  {
+		      /* current metadata style >= v.4.0.0 */
 
-		      if (metadata_version == 3)
-			{
-			    /* current metadata style >= v.4.0.0 */
+		      /* inserting the new UPDATE (timestamp) trigger */
+		      raw = sqlite3_mprintf ("tmu_%s_%s", p_table, p_column);
+		      quoted_trigger = gaiaDoubleQuotedSql (raw);
+		      sqlite3_free (raw);
+		      quoted_table = gaiaDoubleQuotedSql (p_table);
+		      sql_statement =
+			  sqlite3_mprintf
+			  ("CREATE TRIGGER \"%s\" AFTER UPDATE ON \"%s\"\n"
+			   "FOR EACH ROW BEGIN\n"
+			   "UPDATE geometry_columns_time SET last_update = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
+			   "WHERE Lower(f_table_name) = Lower(%Q) AND "
+			   "Lower(f_geometry_column) = Lower(%Q);\nEND",
+			   quoted_trigger, quoted_table, p_table, p_column);
+		      free (quoted_trigger);
+		      free (quoted_table);
+		      ret =
+			  sqlite3_exec (sqlite, sql_statement, NULL, NULL,
+					&errMsg);
+		      sqlite3_free (sql_statement);
+		      if (ret != SQLITE_OK)
+			  goto error;
 
-			    /* inserting the new UPDATE (timestamp) trigger */
-			    raw =
-				sqlite3_mprintf ("tmu_%s_%s", p_table,
-						 p_column);
-			    quoted_trigger = gaiaDoubleQuotedSql (raw);
-			    sqlite3_free (raw);
-			    quoted_table = gaiaDoubleQuotedSql (p_table);
-			    sql_statement =
-				sqlite3_mprintf
-				("CREATE TRIGGER \"%s\" AFTER UPDATE ON \"%s\"\n"
-				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_update = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column);
-			    free (quoted_trigger);
-			    free (quoted_table);
-			    ret =
-				sqlite3_exec (sqlite, sql_statement, NULL, NULL,
-					      &errMsg);
-			    sqlite3_free (sql_statement);
-			    if (ret != SQLITE_OK)
-				goto error;
-
-			    /* inserting the new INSERT (timestamp) trigger */
-			    raw =
-				sqlite3_mprintf ("tmi_%s_%s", p_table,
-						 p_column);
-			    quoted_trigger = gaiaDoubleQuotedSql (raw);
-			    sqlite3_free (raw);
-			    quoted_table = gaiaDoubleQuotedSql (p_table);
-			    sql_statement =
-				sqlite3_mprintf
-				("CREATE TRIGGER \"%s\" AFTER INSERT ON \"%s\"\n"
-				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_insert = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column);
-			    free (quoted_trigger);
-			    free (quoted_table);
-			    ret =
-				sqlite3_exec (sqlite, sql_statement, NULL, NULL,
-					      &errMsg);
-			    sqlite3_free (sql_statement);
-			    if (ret != SQLITE_OK)
-				goto error;
-
-			    /* inserting the new DELETE (timestamp) trigger */
-			    raw =
-				sqlite3_mprintf ("tmd_%s_%s", p_table,
-						 p_column);
-			    quoted_trigger = gaiaDoubleQuotedSql (raw);
-			    sqlite3_free (raw);
-			    quoted_table = gaiaDoubleQuotedSql (p_table);
-			    sql_statement =
-				sqlite3_mprintf
-				("CREATE TRIGGER \"%s\" AFTER DELETE ON \"%s\"\n"
-				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_delete = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column);
-			    free (quoted_trigger);
-			    free (quoted_table);
-			    ret =
-				sqlite3_exec (sqlite, sql_statement, NULL, NULL,
-					      &errMsg);
-			    sqlite3_free (sql_statement);
-			    if (ret != SQLITE_OK)
-				goto error;
-			}
+		      /* inserting the new INSERT (timestamp) trigger */
+		      raw = sqlite3_mprintf ("tmi_%s_%s", p_table, p_column);
+		      quoted_trigger = gaiaDoubleQuotedSql (raw);
+		      sqlite3_free (raw);
+		      quoted_table = gaiaDoubleQuotedSql (p_table);
+		      sql_statement =
+			  sqlite3_mprintf
+			  ("CREATE TRIGGER \"%s\" AFTER INSERT ON \"%s\"\n"
+			   "FOR EACH ROW BEGIN\n"
+			   "UPDATE geometry_columns_time SET last_insert = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
+			   "WHERE Lower(f_table_name) = Lower(%Q) AND "
+			   "Lower(f_geometry_column) = Lower(%Q);\nEND",
+			   quoted_trigger, quoted_table, p_table, p_column);
+		      free (quoted_trigger);
+		      free (quoted_table);
+		      ret =
+			  sqlite3_exec (sqlite, sql_statement, NULL, NULL,
+					&errMsg);
+		      sqlite3_free (sql_statement);
+		      if (ret != SQLITE_OK)
+			  goto error;
+
+		      /* inserting the new DELETE (timestamp) trigger */
+		      raw = sqlite3_mprintf ("tmd_%s_%s", p_table, p_column);
+		      quoted_trigger = gaiaDoubleQuotedSql (raw);
+		      sqlite3_free (raw);
+		      quoted_table = gaiaDoubleQuotedSql (p_table);
+		      sql_statement =
+			  sqlite3_mprintf
+			  ("CREATE TRIGGER \"%s\" AFTER DELETE ON \"%s\"\n"
+			   "FOR EACH ROW BEGIN\n"
+			   "UPDATE geometry_columns_time SET last_delete = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
+			   "WHERE Lower(f_table_name) = Lower(%Q) AND "
+			   "Lower(f_geometry_column) = Lower(%Q);\nEND",
+			   quoted_trigger, quoted_table, p_table, p_column);
+		      free (quoted_trigger);
+		      free (quoted_table);
+		      ret =
+			  sqlite3_exec (sqlite, sql_statement, NULL, NULL,
+					&errMsg);
+		      sqlite3_free (sql_statement);
+		      if (ret != SQLITE_OK)
+			  goto error;
 		  }
 
 		/* deleting the old INSERT trigger SPATIAL_INDEX [if any] */
@@ -3309,13 +3346,10 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 				sqlite3_mprintf
 				("CREATE TRIGGER \"%s\" AFTER INSERT ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_insert = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "DELETE FROM \"%s\" WHERE pkid=NEW.ROWID;\n"
 				 "SELECT RTreeAlign(%Q, NEW.ROWID, NEW.\"%s\");\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree, raw, quoted_column);
+				 quoted_trigger, quoted_table, quoted_rtree,
+				 raw, quoted_column);
 			    sqlite3_free (raw);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
@@ -3374,15 +3408,12 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 			    quoted_column = gaiaDoubleQuotedSql (p_column);
 			    sql_statement =
 				sqlite3_mprintf
-				("CREATE TRIGGER \"%s\" AFTER UPDATE ON \"%s\"\n"
+				("CREATE TRIGGER \"%s\" AFTER UPDATE OF \"%s\" ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_update = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "DELETE FROM \"%s\" WHERE pkid=NEW.ROWID;\n"
 				 "SELECT RTreeAlign(%Q, NEW.ROWID, NEW.\"%s\");\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree, raw, quoted_column);
+				 quoted_trigger, quoted_column, quoted_table,
+				 quoted_rtree, raw, quoted_column);
 			    sqlite3_free (raw);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
@@ -3444,12 +3475,8 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 				sqlite3_mprintf
 				("CREATE TRIGGER \"%s\" AFTER DELETE ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_delete = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "DELETE FROM \"%s\" WHERE pkid=OLD.ROWID;\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree);
+				 quoted_trigger, quoted_table, quoted_rtree);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
 			    free (quoted_table);
@@ -3511,14 +3538,11 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 				sqlite3_mprintf
 				("CREATE TRIGGER \"%s\" AFTER INSERT ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_insert = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "INSERT INTO \"%s\" (rowid, mbr) VALUES (NEW.ROWID,\nBuildMbrFilter("
 				 "MbrMinX(NEW.\"%s\"), MbrMinY(NEW.\"%s\"), MbrMaxX(NEW.\"%s\"), MbrMaxY(NEW.\"%s\")));\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree, quoted_column,
-				 quoted_column, quoted_column, quoted_column);
+				 quoted_trigger, quoted_table, quoted_rtree,
+				 quoted_column, quoted_column, quoted_column,
+				 quoted_column);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
 			    free (quoted_table);
@@ -3578,18 +3602,14 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 			    quoted_column = gaiaDoubleQuotedSql (p_column);
 			    sql_statement =
 				sqlite3_mprintf
-				("CREATE TRIGGER \"%s\" AFTER UPDATE ON \"%s\"\n"
+				("CREATE TRIGGER \"%s\" AFTER UPDATE OF \"%s\" ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_update = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "UPDATE \"%s\" SET mbr = BuildMbrFilter("
 				 "MbrMinX(NEW.\"%s\"), MbrMinY(NEW.\"%s\"), MbrMaxX(NEW.\"%s\"), MbrMaxY(NEW.\"%s\"))\n"
 				 "WHERE rowid = NEW.ROWID;\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree,
-				 quoted_column, quoted_column, quoted_column,
-				 quoted_column);
+				 quoted_trigger, quoted_column, quoted_table,
+				 quoted_rtree, quoted_column, quoted_column,
+				 quoted_column, quoted_column);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
 			    free (quoted_table);
@@ -3651,12 +3671,8 @@ updateGeometryTriggers (void *p_sqlite, const char *table, const char *column)
 				sqlite3_mprintf
 				("CREATE TRIGGER \"%s\" AFTER DELETE ON \"%s\"\n"
 				 "FOR EACH ROW BEGIN\n"
-				 "UPDATE geometry_columns_time SET last_delete = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now')\n"
-				 "WHERE Lower(f_table_name) = Lower(%Q) AND "
-				 "Lower(f_geometry_column) = Lower(%Q);\n"
 				 "DELETE FROM \"%s\" WHERE rowid = OLD.ROWID;\nEND",
-				 quoted_trigger, quoted_table, p_table,
-				 p_column, quoted_rtree);
+				 quoted_trigger, quoted_table, quoted_rtree);
 			    free (quoted_trigger);
 			    free (quoted_rtree);
 			    free (quoted_table);
@@ -4457,11 +4473,11 @@ gaiaGetVectorLayersList_v4 (sqlite3 * handle, const char *table,
 		    (const char *) sqlite3_column_text (stmt, 0);
 		const char *geometry_column =
 		    (const char *) sqlite3_column_text (stmt, 1);
-		int count;
-		double min_x;
-		double min_y;
-		double max_x;
-		double max_y;
+		int count = 0;
+		double min_x = DBL_MAX;
+		double min_y = DBL_MAX;
+		double max_x = 0.0 - DBL_MAX;
+		double max_y = 0.0 - DBL_MAX;
 		if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
 		    is_null = 1;
 		else
@@ -4598,11 +4614,11 @@ gaiaGetVectorLayersList_v4 (sqlite3 * handle, const char *table,
 		int null_max_size = 0;
 		int null_int_range = 0;
 		int null_double_range = 0;
-		int max_size;
+		int max_size = 0;
 		sqlite3_int64 integer_min;
 		sqlite3_int64 integer_max;
-		double double_min;
-		double double_max;
+		double double_min = DBL_MAX;
+		double double_max = 0.0 - DBL_MAX;
 		const char *table_name =
 		    (const char *) sqlite3_column_text (stmt, 0);
 		const char *geometry_column =
@@ -5064,11 +5080,11 @@ get_table_extent_legacy (sqlite3 * handle, const char *table,
 		    (const char *) sqlite3_column_text (stmt, 0);
 		const char *geometry_column =
 		    (const char *) sqlite3_column_text (stmt, 1);
-		int count;
-		double min_x;
-		double min_y;
-		double max_x;
-		double max_y;
+		int count = 0;
+		double min_x = DBL_MAX;
+		double min_y = DBL_MAX;
+		double max_x = 0.0 - DBL_MAX;
+		double max_y = 0.0 - DBL_MAX;
 		if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
 		    is_null = 1;
 		else
@@ -5195,11 +5211,11 @@ get_view_extent_legacy (sqlite3 * handle, const char *table,
 		    (const char *) sqlite3_column_text (stmt, 0);
 		const char *geometry_column =
 		    (const char *) sqlite3_column_text (stmt, 1);
-		int count;
-		double min_x;
-		double min_y;
-		double max_x;
-		double max_y;
+		int count = 0;
+		double min_x = DBL_MAX;
+		double min_y = DBL_MAX;
+		double max_x = 0.0 - DBL_MAX;
+		double max_y = 0.0 - DBL_MAX;
 		if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
 		    is_null = 1;
 		else
diff --git a/src/spatialite/spatialite.c b/src/spatialite/spatialite.c
index ec88f3c..535d7b9 100644
--- a/src/spatialite/spatialite.c
+++ b/src/spatialite/spatialite.c
@@ -64,6 +64,13 @@ Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
 #include <locale.h>
 
 #if defined(_WIN32) && !defined(__MINGW32__)
+#include <io.h>
+#include <direct.h>
+#else
+#include <dirent.h>
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32__)
 #include "config-msvc.h"
 #else
 #include "config.h"
@@ -90,6 +97,10 @@ Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
 #include <spatialite.h>
 #include <spatialite_private.h>
 
+#ifdef ENABLE_LIBXML2		/* LIBXML2 (and thus WFS) enabled */
+#include <spatialite/gg_wfs.h>
+#endif
+
 #ifndef OMIT_GEOS		/* including GEOS */
 #include <geos_c.h>
 #endif
@@ -1684,14 +1695,6 @@ fnct_InitSpatialMetaData (sqlite3_context * context, int argc,
 			     "view 'geom_cols_ref_sys' successfully created");
     if (ret != SQLITE_OK)
 	goto error;
-    if (!createAdvancedMetaData (sqlite))
-	goto error;
-/* creating the SpatialIndex VIRTUAL TABLE */
-    strcpy (sql, "CREATE VIRTUAL TABLE SpatialIndex ");
-    strcat (sql, "USING VirtualSpatialIndex()");
-    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &errMsg);
-    if (ret != SQLITE_OK)
-	goto error;
     if (spatial_ref_sys_init2 (sqlite, mode, 0))
       {
 	  if (mode == GAIA_EPSG_NONE)
@@ -1701,6 +1704,20 @@ fnct_InitSpatialMetaData (sqlite3_context * context, int argc,
 	      updateSpatiaLiteHistory (sqlite, "spatial_ref_sys", NULL,
 				       "table successfully populated");
       }
+    if (!createAdvancedMetaData (sqlite))
+	goto error;
+/* creating the SpatialIndex VIRTUAL TABLE */
+    strcpy (sql, "CREATE VIRTUAL TABLE SpatialIndex ");
+    strcat (sql, "USING VirtualSpatialIndex()");
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &errMsg);
+    if (ret != SQLITE_OK)
+	goto error;
+/* creating the ElementaryGeometries VIRTUAL TABLE */
+    strcpy (sql, "CREATE VIRTUAL TABLE ElementaryGeometries ");
+    strcat (sql, "USING VirtualElementary()");
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &errMsg);
+    if (ret != SQLITE_OK)
+	goto error;
 
     if (transaction)
       {
@@ -1713,7 +1730,7 @@ fnct_InitSpatialMetaData (sqlite3_context * context, int argc,
     sqlite3_result_int (context, 1);
     return;
   error:
-    spatialite_e (" InitSpatiaMetaData() error:\"%s\"\n", errMsg);
+    spatialite_e ("InitSpatiaMetaData() error:\"%s\"\n", errMsg);
     sqlite3_free (errMsg);
     if (transaction)
       {
@@ -1729,6 +1746,224 @@ fnct_InitSpatialMetaData (sqlite3_context * context, int argc,
     return;
 }
 
+static void
+fnct_CloneTable (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ CloneTable(text db_prefix, text in_table, text out_table, integer transaction)
+/ CloneTable(text db_prefix, text in_table, text out_table, integer transaction,
+/            ... text option1 ..., ... text option2 ..., text option10)
+/
+/ cloning a whole table [CREATE and then COPY]
+/ returns 1 on success
+/ 0 on failure (NULL on invalid arguments)
+*/
+    int ret;
+    char *errMsg = NULL;
+    const char *db_prefix;
+    const char *in_table;
+    const char *out_table;
+    int transaction = 0;
+    int active = 0;
+    const void *cloner = NULL;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	db_prefix = (const char *) sqlite3_value_text (argv[0]);
+    else
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 1 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
+	in_table = (const char *) sqlite3_value_text (argv[1]);
+    else
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 2 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[2]) == SQLITE_TEXT)
+	out_table = (const char *) sqlite3_value_text (argv[2]);
+    else
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 3 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER)
+	transaction = sqlite3_value_int (argv[3]);
+    else
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 4 is not of the Integer type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+
+/* additional options */
+    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 5 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 6 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 7 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 8 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 9 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 10 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 11 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 12 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 13 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (argc > 13 && sqlite3_value_type (argv[13]) != SQLITE_TEXT)
+      {
+	  spatialite_e
+	      ("CloneTable() error: argument 14 is not of the String or TEXT type\n");
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+    cloner = gaiaAuxClonerCreate (sqlite, db_prefix, in_table, out_table);
+    if (cloner == NULL)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+/* additional options */
+    if (argc > 4)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[4]));
+    if (argc > 5)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[5]));
+    if (argc > 6)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[6]));
+    if (argc > 7)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[7]));
+    if (argc > 8)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[8]));
+    if (argc > 9)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[9]));
+    if (argc > 10)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[10]));
+    if (argc > 11)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[11]));
+    if (argc > 12)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[12]));
+    if (argc > 13)
+	gaiaAuxClonerAddOption (cloner,
+				(const char *) sqlite3_value_text (argv[13]));
+
+    if (!gaiaAuxClonerCheckValidTarget (cloner))
+	goto error;
+
+    if (transaction)
+      {
+	  /* starting a Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	      goto error;
+      }
+    active = 1;
+
+    if (!gaiaAuxClonerExecute (cloner))
+	goto error;
+    gaiaAuxClonerDestroy (cloner);
+    updateSpatiaLiteHistory (sqlite, out_table, NULL,
+			     "table successfully cloned");
+
+    if (transaction)
+      {
+	  /* confirming the still pending Transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	      goto error;
+      }
+
+    sqlite3_result_int (context, 1);
+    return;
+  error:
+    if (cloner != NULL)
+	gaiaAuxClonerDestroy (cloner);
+    spatialite_e ("CloneTable() error:\"%s\"\n", errMsg);
+    sqlite3_free (errMsg);
+    if (transaction && active)
+      {
+	  /* performing a Rollback */
+	  ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	    {
+		spatialite_e ("CloneTable() error:\"%s\"\n", errMsg);
+		sqlite3_free (errMsg);
+	    }
+      }
+    sqlite3_result_int (context, 0);
+    return;
+}
+
 static int
 checkGeoPackage (sqlite3 * handle)
 {
@@ -2220,10 +2455,10 @@ fnct_AddGeometryColumn (sqlite3_context * context, int argc,
     char *p_table = NULL;
     char *quoted_table;
     char *quoted_column;
-    const char *p_type;
-    const char *p_dims;
-    int n_type;
-    int n_dims;
+    const char *p_type = NULL;
+    const char *p_dims = NULL;
+    int n_type = 0;
+    int n_dims = 0;
     char *sql_statement;
     sqlite3 *sqlite = sqlite3_context_db_handle (context);
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
@@ -2598,7 +2833,7 @@ fnct_AddGeometryColumn (sqlite3_context * context, int argc,
 	  sqlite3_free (p_table);
 	  return;
       }
-/*ok, inserting into geometry_columns [Spatial Metadata] */
+/* ok, inserting into geometry_columns [Spatial Metadata] */
     if (metadata_version == 1)
       {
 	  /* legacy metadata style <= v.3.1.0 */
@@ -2955,8 +3190,8 @@ fnct_RecoverGeometryColumn (sqlite3_context * context, int argc,
     int metadata_version;
     sqlite3_stmt *stmt;
     int exists = 0;
-    const char *p_type;
-    const char *p_dims;
+    const char *p_type = NULL;
+    const char *p_dims = NULL;
     int n_type;
     int n_dims;
     char *sql_statement;
@@ -4089,7 +4324,7 @@ registerVirtual (sqlite3 * sqlite, const char *table)
 /* attempting to register a VirtualGeometry */
     char gtype[64];
     int xtype = -1;
-    int srid;
+    int srid = -1;
     char **results;
     int ret;
     int rows;
@@ -5050,21 +5285,21 @@ check_spatial_index (sqlite3 * sqlite, const unsigned char *table,
     int ret;
     int is_defined = 0;
     sqlite3_stmt *stmt;
-    sqlite3_int64 count_geom;
-    sqlite3_int64 count_rtree;
+    sqlite3_int64 count_geom = 0;
+    sqlite3_int64 count_rtree = 0;
     sqlite3_int64 count_rev = 0;
-    double g_xmin;
-    double g_ymin;
-    double g_xmax;
-    double g_ymax;
+    double g_xmin = DBL_MAX;
+    double g_ymin = DBL_MAX;
+    double g_xmax = 0.0 - DBL_MAX;
+    double g_ymax = 0.0 - DBL_MAX;
     int ok_g_xmin;
     int ok_g_ymin;
     int ok_g_xmax;
     int ok_g_ymax;
-    double i_xmin;
-    double i_ymin;
-    double i_xmax;
-    double i_ymax;
+    double i_xmin = DBL_MAX;
+    double i_ymin = DBL_MAX;
+    double i_xmax = 0.0 - DBL_MAX;
+    double i_ymax = 0.0 - DBL_MAX;
     int ok_i_xmin;
     int ok_i_ymin;
     int ok_i_xmax;
@@ -6191,6 +6426,71 @@ fnct_UpdateLayerStatistics (sqlite3_context * context, int argc,
 }
 
 static void
+fnct_UpgradeGeometryTriggers (sqlite3_context * context, int argc,
+			      sqlite3_value ** argv)
+{
+/* SQL function:
+/ UpgradeGeometryTriggers(transaction TRUE|FALSE)
+/
+/ Upgrades (reinstalls) all Geometry Triggers - requires a DB > 4.0.0
+/ returns 1 on success
+/ 0 on failure (NULL on invalid args)
+*/
+    char *errMsg = NULL;
+    int ret;
+    int transaction = 0;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_INTEGER)
+      {
+	  spatialite_e
+	      ("UpgradeGeometryTriggers() error: argument 1 [TRANSACTION] is not of the Integer type\n");
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+    if (checkSpatialMetaData (sqlite) < 3)
+      {
+	  spatialite_e
+	      ("UpgradeGeometryTriggers() error: invalid DB Layout (< v.4.0.0)\n");
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+    transaction = sqlite3_value_int (argv[0]);
+    if (transaction)
+      {
+	  /* starting a Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	      goto error;
+      }
+    if (!upgradeGeometryTriggers (sqlite))
+	goto error;
+    if (transaction)
+      {
+	  /* committing the still pending Transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	      goto error;
+      }
+    updateSpatiaLiteHistory (sqlite, "ALL-TABLES", NULL,
+			     "Upgraded Geometry Triggers");
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (transaction)
+      {
+	  /* performing a Rollback */
+	  ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &errMsg);
+	  if (ret != SQLITE_OK)
+	      sqlite3_free (errMsg);
+      }
+    sqlite3_result_int (context, 0);
+    return;
+}
+
+static void
 fnct_GetLayerExtent (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
@@ -10638,6 +10938,8 @@ fnct_CastToMulti (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		    geom2->DeclaredType = GAIA_MULTIPOLYGON;
 		else
 		    geom2->DeclaredType = GAIA_GEOMETRYCOLLECTION;
+		if (geo->DeclaredType == GAIA_GEOMETRYCOLLECTION)
+		    geom2->DeclaredType = GAIA_GEOMETRYCOLLECTION;
 		gaiaToSpatiaLiteBlobWkb (geom2, &p_result, &len);
 		gaiaFreeGeomColl (geom2);
 		sqlite3_result_blob (context, p_result, len, free);
@@ -13980,76 +14282,32 @@ fnct_AddPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
-fnct_SetPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
+commont_set_point (sqlite3_context * context, gaiaGeomCollPtr line,
+		   int position, gaiaGeomCollPtr point)
 {
-/* SQL functions:
-/ ST_SetPoint(BLOB encoded LINESTRING line, INTEGER position, BLOB encoded POINT point)
-/
-/ returns a new Linestring by replacing the Point at "position" (zero-based index)
-/ or NULL if any error is encountered
-*/
-    unsigned char *p_blob;
-    int n_bytes;
+/* SetPoint - common implementation */
+    gaiaGeomCollPtr out;
     gaiaLinestringPtr ln;
     gaiaLinestringPtr out_ln;
     gaiaPointPtr pt;
-    int position;
-    gaiaGeomCollPtr line = NULL;
-    gaiaGeomCollPtr point = NULL;
-    gaiaGeomCollPtr out;
-    int len;
     unsigned char *p_result = NULL;
+    int len;
     int iv;
-    double x;
-    double y;
-    double m;
-    double z;
-    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
-    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+    double x = 0.0;
+    double y = 0.0;
+    double m = 0.0;
+    double z = 0.0;
+
+    if (is_single_linestring (line) && is_single_point (point))
+	;
+    else
       {
 	  sqlite3_result_null (context);
-	  return;
+	  goto stop;
       }
-    p_blob = (unsigned char *) sqlite3_value_blob (argv[0]);
-    n_bytes = sqlite3_value_bytes (argv[0]);
-    line = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
-    if (!line)
-      {
-	  sqlite3_result_null (context);
-	  return;
-      }
-    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
-      {
-	  gaiaFreeGeomColl (line);
-	  sqlite3_result_null (context);
-	  return;
-      }
-    position = sqlite3_value_int (argv[1]);
-    if (sqlite3_value_type (argv[2]) != SQLITE_BLOB)
-      {
-	  gaiaFreeGeomColl (line);
-	  sqlite3_result_null (context);
-	  return;
-      }
-    p_blob = (unsigned char *) sqlite3_value_blob (argv[2]);
-    n_bytes = sqlite3_value_bytes (argv[2]);
-    point = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
-    if (!point)
-      {
-	  gaiaFreeGeomColl (line);
-	  sqlite3_result_null (context);
-	  return;
-      }
-    if (is_single_linestring (line) && is_single_point (point))
-	;
-    else
-      {
-	  sqlite3_result_null (context);
-	  goto stop;
-      }
-    ln = line->FirstLinestring;
-    pt = point->FirstPoint;
-    if (position < 0 || position >= ln->Points)
+    ln = line->FirstLinestring;
+    pt = point->FirstPoint;
+    if (position < 0 || position >= ln->Points)
       {
 	  sqlite3_result_null (context);
 	  goto stop;
@@ -14118,6 +14376,164 @@ fnct_SetPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
+fnct_SetPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL functions:
+/ ST_SetPoint(BLOB encoded LINESTRING line, INTEGER position, BLOB encoded POINT point)
+/
+/ returns a new Linestring by replacing the Point at "position" (zero-based index)
+/ or NULL if any error is encountered
+*/
+    unsigned char *p_blob;
+    int n_bytes;
+    int position;
+    gaiaGeomCollPtr line = NULL;
+    gaiaGeomCollPtr point = NULL;
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[0]);
+    n_bytes = sqlite3_value_bytes (argv[0]);
+    line = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!line)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    position = sqlite3_value_int (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_BLOB)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[2]);
+    n_bytes = sqlite3_value_bytes (argv[2]);
+    point = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!point)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    commont_set_point (context, line, position, point);
+}
+
+static void
+fnct_SetStartPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL functions:
+/ ST_SetStartPoint(BLOB encoded LINESTRING line, BLOB encoded POINT point)
+/
+/ returns a new Linestring by replacing its StartPoint
+/ or NULL if any error is encountered
+*/
+    unsigned char *p_blob;
+    int n_bytes;
+    gaiaGeomCollPtr line = NULL;
+    gaiaGeomCollPtr point = NULL;
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[0]);
+    n_bytes = sqlite3_value_bytes (argv[0]);
+    line = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!line)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) != SQLITE_BLOB)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[1]);
+    n_bytes = sqlite3_value_bytes (argv[1]);
+    point = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!point)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    commont_set_point (context, line, 0, point);
+}
+
+static void
+fnct_SetEndPoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL functions:
+/ ST_SetEndPoint(BLOB encoded LINESTRING line, BLOB encoded POINT point)
+/
+/ returns a new Linestring by replacing its EndPoint
+/ or NULL if any error is encountered
+*/
+    unsigned char *p_blob;
+    int n_bytes;
+    gaiaLinestringPtr ln;
+    gaiaGeomCollPtr line = NULL;
+    gaiaGeomCollPtr point = NULL;
+    int position;
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[0]);
+    n_bytes = sqlite3_value_bytes (argv[0]);
+    line = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!line)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) != SQLITE_BLOB)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    p_blob = (unsigned char *) sqlite3_value_blob (argv[1]);
+    n_bytes = sqlite3_value_bytes (argv[1]);
+    point = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+    if (!point)
+      {
+	  gaiaFreeGeomColl (line);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    if (is_single_linestring (line) && is_single_point (point))
+	;
+    else
+      {
+	  sqlite3_result_null (context);
+	  goto stop;
+      }
+    ln = line->FirstLinestring;
+    position = ln->Points - 1;
+    commont_set_point (context, line, position, point);
+    return;
+  stop:
+    gaiaFreeGeomColl (line);
+    gaiaFreeGeomColl (point);
+}
+
+static void
 fnct_RemovePoint (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL functions:
@@ -14382,8 +14798,8 @@ fnct_SnapToGrid (sqlite3_context * context, int argc, sqlite3_value ** argv)
     double origin_y = 0.0;
     double origin_z = 0.0;
     double origin_m = 0.0;
-    double size_x;
-    double size_y;
+    double size_x = 0.0;
+    double size_y = 0.0;
     double size_z = 0.0;
     double size_m = 0.0;
     gaiaGeomCollPtr geo = NULL;
@@ -17923,7 +18339,7 @@ fnct_Union_final (sqlite3_context * context)
     gaiaGeomCollPtr tmp;
     struct gaia_geom_chain *chain;
     struct gaia_geom_chain_item *item;
-    gaiaGeomCollPtr aggregate;
+    gaiaGeomCollPtr aggregate = NULL;
     gaiaGeomCollPtr result;
     void *data = sqlite3_user_data (context);
     struct gaia_geom_chain **p = sqlite3_aggregate_context (context, 0);
@@ -18830,10 +19246,10 @@ fnct_PtDistWithin (sqlite3_context * context, int argc, sqlite3_value ** argv)
     gaiaPolygonPtr pg;
     double ref_dist;
     int use_spheroid = 0;
-    double x0;
-    double y0;
-    double x1;
-    double y1;
+    double x0 = 0.0;
+    double y0 = 0.0;
+    double x1 = 0.0;
+    double y1 = 0.0;
     int pt0 = 0;
     int ln0 = 0;
     int pg0 = 0;
@@ -25395,6 +25811,9 @@ guess_mime_type (const unsigned char *p_blob, int n_bytes)
       case GAIA_PNG_BLOB:
 	  mime = "image/png";
 	  break;
+      case GAIA_JP2_BLOB:
+	  mime = "image/jp2";
+	  break;
       case GAIA_JPEG_BLOB:
       case GAIA_EXIF_BLOB:
       case GAIA_EXIF_GPS_BLOB:
@@ -25452,7 +25871,7 @@ blob_guess (sqlite3_context * context, int argc, sqlite3_value ** argv,
 /* SQL function:
 / IsGifBlob(BLOB encoded image)
 / IsPngBlob, IsJpegBlob, IsExifBlob, IsExifGpsBlob, IsTiffBlob,
-/ IsZipBlob, IsPdfBlob,IsGeometryBlob
+/ IsZipBlob, IsPdfBlob, IsJP2Blob, IsGeometryBlob
 /
 / returns:
 / 1 if the required BLOB_TYPE is TRUE
@@ -25556,6 +25975,14 @@ blob_guess (sqlite3_context * context, int argc, sqlite3_value ** argv,
 	      sqlite3_result_int (context, 0);
 	  return;
       }
+    if (request == GAIA_JP2_BLOB)
+      {
+	  if (blob_type == GAIA_JP2_BLOB)
+	      sqlite3_result_int (context, 1);
+	  else
+	      sqlite3_result_int (context, 0);
+	  return;
+      }
     sqlite3_result_int (context, -1);
 }
 
@@ -25625,6 +26052,12 @@ fnct_IsWebPBlob (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
+fnct_IsJP2Blob (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+    blob_guess (context, argc, argv, GAIA_JP2_BLOB);
+}
+
+static void
 fnct_BlobFromFile (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
@@ -25735,100 +26168,1330 @@ fnct_BlobToFile (sqlite3_context * context, int argc, sqlite3_value ** argv)
     sqlite3_result_int (context, ret);
 }
 
+static int
+load_dxf (sqlite3 * db_handle, struct splite_internal_cache *cache,
+	  char *filename, int srid, int append, int force_dims, int mode,
+	  int special_rings, char *prefix, char *layer_name)
+{
+/* scanning a Directory and processing all DXF files */
+    int ret;
+    gaiaDxfParserPtr dxf = NULL;
+
+/* creating a DXF parser */
+    dxf = gaiaCreateDxfParser (srid, force_dims, prefix, layer_name,
+			       special_rings);
+    if (dxf == NULL)
+      {
+	  ret = 0;
+	  goto stop_dxf;
+      }
+/* attempting to parse the DXF input file */
+    if (gaiaParseDxfFile_r (cache, dxf, filename))
+      {
+	  /* loading into the DB */
+	  if (!gaiaLoadFromDxfParser (db_handle, dxf, mode, append))
+	    {
+		ret = 0;
+		spatialite_e ("DB error while loading: %s\n", filename);
+	    }
+      }
+    else
+      {
+	  ret = 0;
+	  spatialite_e ("Unable to parse: %s\n", filename);
+	  goto stop_dxf;
+      }
+    spatialite_e ("\n*** DXF file succesfully loaded\n");
+    ret = 1;
+
+  stop_dxf:
+    /* destroying the DXF parser */
+    gaiaDestroyDxfParser (dxf);
+    return ret;
+}
+
 static void
-fnct_ExportDXF (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_ImportDXF (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ ExportDXF(TEXT out_dir, TEXT filename, TEXT sql_query, TEXT layer_col_name,
-/           TEXT geom_col_name, TEXT label_col_name, TEXT text_height_col_name,
-/           TEXT text_rotation_col_name, BLOB geom_filter)
+/ ImportDXF(TEXT filename)
 /     or
-/ ExportDXF(TEXT out_dir, TEXT filename, TEXT sql_query, TEXT layer_col_name,
-/           TEXT geom_col_name, TEXT label_col_name, TEXT text_height_col_name,
-/           TEXT text_rotation_col_name, BLOB geom_filter, INT precision)
+/ InportDXF(TEXT filename, INT srid, INT append, TEXT dims,
+/           TEXT mode, TEXT special_rings, TEXT table_prefix,
+/           TEXT layer_name)
 /
 / returns:
 / 1 on success
 / or 0 on failure
+/ NULL on invalid arguments
 */
-    unsigned char *p_blob;
-    int n_bytes;
-    char *path;
-    const char *dir_path = NULL;
-    const char *filename = NULL;
-    FILE *out = NULL;
-    const char *sql_query = NULL;
-    const char *layer_col_name = NULL;
-    const char *geom_col_name = NULL;
-    const char *label_col_name = NULL;
-    const char *text_height_col_name = NULL;
-    const char *text_rotation_col_name = NULL;
-    gaiaGeomCollPtr geom = NULL;
-    int precision = 3;
-    int ret = 1;
+    int ret;
+    char *filename;
+    int srid = -1;
+    int append = 0;
+    int special_rings = GAIA_DXF_RING_NONE;
+    int mode = GAIA_DXF_IMPORT_BY_LAYER;
+    int force_dims = GAIA_DXF_AUTO_2D_3D;
+    char *prefix = NULL;
+    char *layer_name = NULL;
     sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    struct splite_internal_cache *cache = sqlite3_user_data (context);
     GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
-    if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
-	dir_path = (const char *) sqlite3_value_text (argv[0]);
-    if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
-	filename = (const char *) sqlite3_value_text (argv[1]);
-    if (sqlite3_value_type (argv[2]) == SQLITE_TEXT)
-	sql_query = (const char *) sqlite3_value_text (argv[2]);
-    if (sqlite3_value_type (argv[3]) == SQLITE_TEXT)
-	layer_col_name = (const char *) sqlite3_value_text (argv[3]);
-    if (sqlite3_value_type (argv[4]) == SQLITE_TEXT)
-	geom_col_name = (const char *) sqlite3_value_text (argv[4]);
-    if (sqlite3_value_type (argv[5]) == SQLITE_TEXT)
-	label_col_name = (const char *) sqlite3_value_text (argv[5]);
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    filename = (char *) sqlite3_value_text (argv[0]);
+    if (argc > 7)
+      {
+	  const char *value;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  srid = sqlite3_value_int (argv[1]);
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  append = sqlite3_value_int (argv[2]);
+	  if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[3]);
+	  if (strcasecmp (value, "2D") == 0)
+	      force_dims = GAIA_DXF_FORCE_2D;
+	  else if (strcasecmp (value, "3D") == 0)
+	      force_dims = GAIA_DXF_FORCE_3D;
+	  else if (strcasecmp (value, "AUTO") == 0)
+	      force_dims = GAIA_DXF_AUTO_2D_3D;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[4]);
+	  if (strcasecmp (value, "MIXED") == 0)
+	      mode = GAIA_DXF_IMPORT_MIXED;
+	  else if (strcasecmp (value, "DISTINCT") == 0)
+	      mode = GAIA_DXF_IMPORT_BY_LAYER;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[5]);
+	  if (strcasecmp (value, "LINKED") == 0)
+	      special_rings = GAIA_DXF_RING_LINKED;
+	  else if (strcasecmp (value, "UNLINKED") == 0)
+	      special_rings = GAIA_DXF_RING_UNLINKED;
+	  else if (strcasecmp (value, "NONE") == 0)
+	      special_rings = GAIA_DXF_RING_NONE;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[6]) == SQLITE_TEXT)
+	      prefix = (char *) sqlite3_value_text (argv[6]);
+	  else if (sqlite3_value_type (argv[6]) != SQLITE_NULL)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[7]) == SQLITE_TEXT)
+	      layer_name = (char *) sqlite3_value_text (argv[7]);
+	  else if (sqlite3_value_type (argv[7]) != SQLITE_NULL)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+      }
+
+    ret =
+	load_dxf (db_handle, cache, filename, srid, append, force_dims, mode,
+		  special_rings, prefix, layer_name);
+    sqlite3_result_int (context, ret);
+}
+
+static int
+is_dxf_file (const char *filename)
+{
+/* testing if a FileName ends with the expected suffix */
+    int len = strlen (filename);
+    int off = len - 4;
+    if (off >= 1)
+      {
+	  if (strcasecmp (filename + off, ".dxf") == 0)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+scan_dxf_dir (sqlite3 * db_handle, struct splite_internal_cache *cache,
+	      char *dir_path, int srid, int append, int force_dims, int mode,
+	      int special_rings, char *prefix, char *layer_name)
+{
+/* scanning a Directory and processing all DXF files */
+    int cnt = 0;
+    char *filepath;
+#if defined(_WIN32) && !defined(__MINGW32__)
+/* Visual Studio .NET */
+    struct _finddata_t c_file;
+    intptr_t hFile;
+    if (_chdir (dir_path) < 0)
+	return 0;
+    if ((hFile = _findfirst ("*.*", &c_file)) == -1L)
+	;
+    else
+      {
+	  while (1)
+	    {
+		if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+		    || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+		  {
+		      if (is_dxf_file (entry->d_name))
+			{
+			    filepath =
+				sqlite3_mprintf ("%s/%s", dir_path,
+						 c_file.name);
+			    cnt +=
+				load_dxf (db_handle, cache, filepath, srid,
+					  append, force_dims, mode,
+					  special_rings, prefix, layer_name);
+			    sqlite3_free (filepath);
+			}
+		  }
+		if (_findnext (hFile, &c_file) != 0)
+		    break;
+	    };
+	  _findclose (hFile);
+      re}
+#else
+/* not Visual Studio .NET */
+    struct dirent *entry;
+    DIR *dir = opendir (dir_path);
+    if (!dir)
+	return 0;
+    while (1)
+      {
+	  /* scanning dir-entries */
+	  entry = readdir (dir);
+	  if (!entry)
+	      break;
+	  if (is_dxf_file (entry->d_name))
+	    {
+		filepath = sqlite3_mprintf ("%s/%s", dir_path, entry->d_name);
+		cnt +=
+		    load_dxf (db_handle, cache, filepath, srid, append,
+			      force_dims, mode, special_rings, prefix,
+			      layer_name);
+		sqlite3_free (filepath);
+	    }
+      }
+    closedir (dir);
+#endif
+    return cnt;
+}
+
+static void
+fnct_ImportDXFfromDir (sqlite3_context * context, int argc,
+		       sqlite3_value ** argv)
+{
+/* SQL function:
+/ ImportDXFfromDir(TEXT dir_path)
+/     or
+/ InportDXFfromDir(TEXT dir_path, INT srid, INT append, TEXT dims,
+/                  TEXT mode, TEXT special_rings, TEXT table_prefix,
+/                  TEXT layer_name)
+/
+/ returns:
+/ 1 on success
+/ or 0 on failure
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *dir_path;
+    int srid = -1;
+    int append = 0;
+    int special_rings = GAIA_DXF_RING_NONE;
+    int mode = GAIA_DXF_IMPORT_BY_LAYER;
+    int force_dims = GAIA_DXF_AUTO_2D_3D;
+    char *prefix = NULL;
+    char *layer_name = NULL;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    struct splite_internal_cache *cache = sqlite3_user_data (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    dir_path = (char *) sqlite3_value_text (argv[0]);
+    if (argc > 7)
+      {
+	  const char *value;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  srid = sqlite3_value_int (argv[1]);
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  append = sqlite3_value_int (argv[2]);
+	  if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[3]);
+	  if (strcasecmp (value, "2D") == 0)
+	      force_dims = GAIA_DXF_FORCE_2D;
+	  else if (strcasecmp (value, "3D") == 0)
+	      force_dims = GAIA_DXF_FORCE_3D;
+	  else if (strcasecmp (value, "AUTO") == 0)
+	      force_dims = GAIA_DXF_AUTO_2D_3D;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[4]);
+	  if (strcasecmp (value, "MIXED") == 0)
+	      mode = GAIA_DXF_IMPORT_MIXED;
+	  else if (strcasecmp (value, "DISTINCT") == 0)
+	      mode = GAIA_DXF_IMPORT_BY_LAYER;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  value = (const char *) sqlite3_value_text (argv[5]);
+	  if (strcasecmp (value, "LINKED") == 0)
+	      special_rings = GAIA_DXF_RING_LINKED;
+	  else if (strcasecmp (value, "UNLINKED") == 0)
+	      special_rings = GAIA_DXF_RING_UNLINKED;
+	  else if (strcasecmp (value, "NONE") == 0)
+	      special_rings = GAIA_DXF_RING_NONE;
+	  else
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[6]) == SQLITE_TEXT)
+	      prefix = (char *) sqlite3_value_text (argv[6]);
+	  else if (sqlite3_value_type (argv[6]) != SQLITE_NULL)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  if (sqlite3_value_type (argv[7]) == SQLITE_TEXT)
+	      layer_name = (char *) sqlite3_value_text (argv[7]);
+	  else if (sqlite3_value_type (argv[7]) != SQLITE_NULL)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+      }
+
+    ret =
+	scan_dxf_dir (db_handle, cache, dir_path, srid, append, force_dims,
+		      mode, special_rings, prefix, layer_name);
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_ExportDXF (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportDXF(TEXT out_dir, TEXT filename, TEXT sql_query, TEXT layer_col_name,
+/           TEXT geom_col_name, TEXT label_col_name, TEXT text_height_col_name,
+/           TEXT text_rotation_col_name, BLOB geom_filter)
+/     or
+/ ExportDXF(TEXT out_dir, TEXT filename, TEXT sql_query, TEXT layer_col_name,
+/           TEXT geom_col_name, TEXT label_col_name, TEXT text_height_col_name,
+/           TEXT text_rotation_col_name, BLOB geom_filter, INT precision)
+/
+/ returns:
+/ 1 on success
+/ or 0 on failure
+*/
+    unsigned char *p_blob;
+    int n_bytes;
+    char *path;
+    const char *dir_path = NULL;
+    const char *filename = NULL;
+    FILE *out = NULL;
+    const char *sql_query = NULL;
+    const char *layer_col_name = NULL;
+    const char *geom_col_name = NULL;
+    const char *label_col_name = NULL;
+    const char *text_height_col_name = NULL;
+    const char *text_rotation_col_name = NULL;
+    gaiaGeomCollPtr geom = NULL;
+    int precision = 3;
+    int ret = 1;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	dir_path = (const char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
+	filename = (const char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) == SQLITE_TEXT)
+	sql_query = (const char *) sqlite3_value_text (argv[2]);
+    if (sqlite3_value_type (argv[3]) == SQLITE_TEXT)
+	layer_col_name = (const char *) sqlite3_value_text (argv[3]);
+    if (sqlite3_value_type (argv[4]) == SQLITE_TEXT)
+	geom_col_name = (const char *) sqlite3_value_text (argv[4]);
+    if (sqlite3_value_type (argv[5]) == SQLITE_TEXT)
+	label_col_name = (const char *) sqlite3_value_text (argv[5]);
     if (sqlite3_value_type (argv[6]) == SQLITE_TEXT)
 	text_height_col_name = (const char *) sqlite3_value_text (argv[6]);
     if (sqlite3_value_type (argv[7]) == SQLITE_TEXT)
 	text_rotation_col_name = (const char *) sqlite3_value_text (argv[7]);
     if (sqlite3_value_type (argv[8]) == SQLITE_BLOB)
       {
-	  p_blob = (unsigned char *) sqlite3_value_blob (argv[8]);
-	  n_bytes = sqlite3_value_bytes (argv[8]);
-	  geom = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+	  p_blob = (unsigned char *) sqlite3_value_blob (argv[8]);
+	  n_bytes = sqlite3_value_bytes (argv[8]);
+	  geom = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
+      }
+    if (argc == 10)
+      {
+	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+	      precision = sqlite3_value_int (argv[9]);
+      }
+    if (dir_path == NULL || filename == NULL || sql_query == NULL
+	|| layer_col_name == NULL || geom_col_name == NULL)
+      {
+	  sqlite3_result_int (context, 0);
+	  if (geom != NULL)
+	      gaiaFreeGeomColl (geom);
+	  return;
+      }
+
+    path = sqlite3_mprintf ("%s/%s.dxf", dir_path, filename);
+    out = fopen (path, "wb");
+    if (out == NULL)
+      {
+	  ret = 0;
+	  spatialite_e ("ExportDXF error - unable to create \"%s\"\n", path);
+      }
+    else
+      {
+	  /* exporting the DXF */
+	  gaiaDxfWriter dxf;
+	  gaiaDxfWriterInit (&dxf, out, precision, GAIA_DXF_V12);
+	  ret = gaiaExportDxf (&dxf, db_handle, sql_query, layer_col_name,
+			       geom_col_name, label_col_name,
+			       text_height_col_name, text_rotation_col_name,
+			       geom);
+	  if (ret > 0)
+	      ret = 1;
+	  fclose (out);
+      }
+    sqlite3_result_int (context, ret);
+    if (geom != NULL)
+	gaiaFreeGeomColl (geom);
+    sqlite3_free (path);
+}
+
+static void
+fnct_CheckDuplicateRows (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ CheckDuplicateRows(TEXT table)
+/
+/ returns:
+/ the number of duplicate rows found
+/ NULL on invalid arguments
+*/
+    char *table;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+
+    check_duplicated_rows (db_handle, table, &rows);
+
+    if (rows < 0)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_RemoveDuplicateRows (sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
+{
+/* SQL function:
+/ RemoveDuplicateRows(TEXT table)
+/
+/ returns:
+/ the number of duplicate rows removed
+/ NULL on invalid arguments
+*/
+    char *table;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+
+    remove_duplicated_rows_ex (db_handle, table, &rows);
+
+    if (rows < 0)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ElementaryGeometries (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ ElementaryGeometries(TEXT input_table, TEXT geo_column, TEXT out_table,
+/                      TEXT out_pk, TEXT out_multi_id)
+/
+/ returns:
+/ the number of inserted rows
+/ NULL on invalid arguments
+*/
+    char *in_table;
+    char *geo_column;
+    char *out_table;
+    char *out_pk;
+    char *out_multi_id;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    in_table = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    geo_column = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    out_table = (char *) sqlite3_value_text (argv[2]);
+    if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    out_pk = (char *) sqlite3_value_text (argv[3]);
+    if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    out_multi_id = (char *) sqlite3_value_text (argv[4]);
+
+    elementary_geometries_ex (db_handle, in_table, geo_column, out_table,
+			      out_pk, out_multi_id, &rows);
+
+    if (rows <= 0)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_DropGeoTable (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ DropGeoTable(TEXT table)
+/ DropGeoTable(TEXT db_prefix, TEXT table)
+/
+/ returns:
+/ 1 on success, 0 on failure
+/ NULL on invalid arguments
+*/
+    char *db_prefix = "main";
+    char *table;
+    int ret;
+    int cnt;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (argc > 1)
+      {
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  db_prefix = (char *) sqlite3_value_text (argv[0]);
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  table = (char *) sqlite3_value_text (argv[1]);
+      }
+    else
+      {
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  table = (char *) sqlite3_value_text (argv[0]);
+      }
+
+    cnt = sqlite3_total_changes (db_handle);
+    ret = gaiaDropTableEx (db_handle, db_prefix, table);
+    if (ret)
+      {
+	  if (sqlite3_total_changes (db_handle) <= cnt)
+	      ret = 0;
+      }
+
+    sqlite3_result_int (context, ret);
+}
+
+#ifndef OMIT_FREEXL		/* FREEXL is enabled */
+static void
+fnct_ImportXLS (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ImportXLS(TEXT filename, TEXT table)
+/ ImportXLS(TEXT filename, TEXT table, INT worksheet_index)
+/ ImportXLS(TEXT filename, TEXT table, INT worksheet_index,
+/          INT first_line_titles)
+/
+/ returns:
+/ the number of inserted rows
+/ NULL on invalid arguments
+*/
+    const char *filename;
+    const char *table;
+    int widx;
+    unsigned int worksheet_index = 0;
+    int first_line_titles = 0;
+    int ret;
+    unsigned int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    filename = (const char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (const char *) sqlite3_value_text (argv[1]);
+    if (argc > 2)
+      {
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  widx = sqlite3_value_int (argv[2]);
+	  if (widx < 0)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  worksheet_index = widx;
+      }
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  first_line_titles = sqlite3_value_int (argv[3]);
+      }
+
+    ret =
+	load_XL (db_handle, filename, table, worksheet_index, first_line_titles,
+		 &rows, NULL);
+
+    if (!ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+#endif /* end FREEXL support */
+
+static void
+fnct_ImportDBF (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ImportDBF(TEXT filename, TEXT table, TEXT charset)
+/ ImportDBF(TEXT filename, TEXT table, TEXT charset, TEXT pk_column)
+/ ImportDBF(TEXT filename, TEXT table, TEXT charset, TEXT pk_column,
+/           INTEGER text_dates)
+/
+/ returns:
+/ the number of inserted rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *path;
+    char *charset;
+    char *pk_column = NULL;
+    int text_dates = 0;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    path = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    charset = (char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      pk_column = (char *) sqlite3_value_text (argv[3]);
+      }
+    if (argc > 4)
+      {
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      text_dates = sqlite3_value_int (argv[4]);
+      }
+
+    ret =
+	load_dbf_ex2 (db_handle, path, table, pk_column, charset, 1, text_dates,
+		      &rows, NULL);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ExportDBF (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportDBF(TEXT table, TEXT filename, TEXT charset)
+/
+/ returns:
+/ the number of exported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *path;
+    char *charset;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    path = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    charset = (char *) sqlite3_value_text (argv[2]);
+
+    ret = dump_dbf_ex (db_handle, table, path, charset, &rows, NULL);
+
+    if (rows <= 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ImportSHP (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset)
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid)
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column)
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column)
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column, TEXT geom_type)
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column, TEXT geom_type,
+/           INT coerce2d) 
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column, TEXT geom_type,
+/           INT coerce2d, INT compressed) 
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column, TEXT geom_type,
+/           INT coerce2d, INT compressed, INT spatial_index) 
+/ ImportSHP(TEXT filename, TEXT table, TEXT charset, INT srid, 
+/           TEXT geom_column, TEXT pk_column, TEXT geom_type,
+/           INT coerce2d, INT compressed, INT spatial_index,
+/           INT text_dates)
+/
+/ returns:
+/ the number of imported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *path;
+    char *charset;
+    int srid = -1;
+    int coerce2d = 0;
+    int compressed = 0;
+    int spatial_index = 0;
+    int text_dates = 0;
+    char *pk_column = NULL;
+    char *geo_column = NULL;
+    char *geom_type = NULL;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    path = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    charset = (char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      srid = sqlite3_value_int (argv[3]);
+      }
+    if (argc > 4)
+      {
+	  if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      geo_column = (char *) sqlite3_value_text (argv[4]);
+      }
+    if (argc > 5)
+      {
+	  if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      pk_column = (char *) sqlite3_value_text (argv[5]);
+      }
+    if (argc > 6)
+      {
+	  if (sqlite3_value_type (argv[6]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      geom_type = (char *) sqlite3_value_text (argv[6]);
+      }
+    if (argc > 7)
+      {
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      coerce2d = sqlite3_value_int (argv[7]);
+      }
+    if (argc > 8)
+      {
+	  if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      compressed = sqlite3_value_int (argv[8]);
+      }
+    if (argc > 9)
+      {
+	  if (sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      spatial_index = sqlite3_value_int (argv[9]);
+      }
+    if (argc > 10)
+      {
+	  if (sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      text_dates = sqlite3_value_int (argv[10]);
+      }
+
+    ret =
+	load_shapefile_ex2 (db_handle, path, table, charset, srid, geo_column,
+			    geom_type, pk_column, coerce2d, compressed, 1,
+			    spatial_index, text_dates, &rows, NULL);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ExportSHP (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportSHP(TEXT table, TEXT geom_column, TEXT filename, TEXT charset)
+/ ExportSHP(TEXT table, TEXT geom_column, TEXT filename, TEXT charset,
+/           TEXT geom_type)
+/
+/ returns:
+/ the number of exported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *column;
+    char *path;
+    char *charset;
+    char *geom_type = NULL;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    column = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
       }
-    if (argc == 10)
+    path = (char *) sqlite3_value_text (argv[2]);
+    if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
       {
-	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
-	      precision = sqlite3_value_int (argv[9]);
+	  sqlite3_result_null (context);
+	  return;
       }
-    if (dir_path == NULL || filename == NULL || sql_query == NULL
-	|| layer_col_name == NULL || geom_col_name == NULL)
+    charset = (char *) sqlite3_value_text (argv[3]);
+    if (argc > 4)
       {
-	  sqlite3_result_int (context, 0);
-	  if (geom != NULL)
-	      gaiaFreeGeomColl (geom);
+	  if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      geom_type = (char *) sqlite3_value_text (argv[4]);
+      }
+
+    ret =
+	dump_shapefile (db_handle, table, column, path, charset, geom_type, 1,
+			&rows, NULL);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ExportKML (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportKML(TEXT table, TEXT geom_column, TEXT filename)
+/ ExportKML(TEXT table, TEXT geom_column, TEXT filename, INT precision)
+/ ExportKML(TEXT table, TEXT geom_column, TEXT filename, INT precision,
+/           TEXT name_column)
+/ ExportKML(TEXT table, TEXT geom_column, TEXT filename, INT precision,
+/           TEXT name_column, TEXT description_column)
+/
+/ returns:
+/ the number of exported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *geom_col;
+    char *path;
+    int precision = 8;
+    char *name_col = NULL;
+    char *descr_col = NULL;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    geom_col = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
 	  return;
       }
+    path = (char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      precision = sqlite3_value_int (argv[3]);
+      }
+    if (argc > 4)
+      {
+	  if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      name_col = (char *) sqlite3_value_text (argv[4]);
+      }
+    if (argc > 5)
+      {
+	  if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      descr_col = (char *) sqlite3_value_text (argv[5]);
+      }
 
-    path = sqlite3_mprintf ("%s/%s.dxf", dir_path, filename);
-    out = fopen (path, "wb");
-    if (out == NULL)
+    ret =
+	dump_kml_ex (db_handle, table, geom_col, path, name_col, descr_col,
+		     precision, &rows);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
+}
+
+static void
+fnct_ExportGeoJSON (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportGeoJSON(TEXT table, TEXT geom_column, TEXT filename)
+/ ExportGeoJSON(TEXT table, TEXT geom_column, TEXT filename, 
+/               TEXT format)
+/ ExportGeoJSON(TEXT table, TEXT geom_column, TEXT filename, 
+/               TEXT format, INT precision)
+/
+/ returns:
+/ the number of exported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *table;
+    char *geom_col;
+    char *path;
+    int format = 0;
+    int precision = 8;
+    char *fmt = NULL;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
       {
-	  ret = 0;
-	  spatialite_e ("ExportDXF error - unable to create \"%s\"\n", path);
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    geom_col = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    path = (char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	    {
+		fmt = (char *) sqlite3_value_text (argv[3]);
+		if (strcasecmp (fmt, "none") == 0)
+		    format = 0;
+		else if (strcasecmp (fmt, "MBR") == 0)
+		    format = 1;
+		else if (strcasecmp (fmt, "withShortCRS") == 0)
+		    format = 2;
+		else if (strcasecmp (fmt, "MBRwithShortCRS") == 0)
+		    format = 3;
+		else if (strcasecmp (fmt, "withLongCRS") == 0)
+		    format = 4;
+		else if (strcasecmp (fmt, "MBRwithLongCRS") == 0)
+		    format = 5;
+		else
+		  {
+		      sqlite3_result_null (context);
+		      return;
+		  }
+	    }
+      }
+    if (argc > 4)
+      {
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      precision = sqlite3_value_int (argv[4]);
       }
+
+    ret =
+	dump_geojson_ex (db_handle, table, geom_col, path, precision, format,
+			 &rows);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
     else
+	sqlite3_result_int (context, rows);
+}
+
+#ifdef ENABLE_LIBXML2		/* including LIBXML2 */
+static void
+wfs_page_done (int features, void *ptr)
+{
+/* WFS progress handler callback */
+    if (ptr == NULL)
+	ptr = NULL;		/* silencing stupid compiler warnings */
+    if (isatty (1))
+	spatialite_e ("WFS Features loaded since now: %d\r", features);
+}
+
+static void
+fnct_ImportWFS (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ ImportWFS(TEXT filename_or_url, TEXT layer_name, TEXT table)
+/ ImportWFS(TEXT filename_or_url, TEXT layer_name, TEXT table,
+/           TEXT pk_column)
+/ ImportWFS(TEXT filename_or_url, TEXT layer_name, TEXT table,
+/           TEXT pk_column, INT swap_axes)
+/ ImportWFS(TEXT filename_or_url, TEXT layer_name, TEXT table,
+/           TEXT pk_column, INT swap_axes, INT page_size)
+/ ImportWFS(TEXT filename_or_url, TEXT layer_name, TEXT table,
+/           TEXT pk_column, INT swap_axes, INT page_size,
+/           INT spatial_index)
+/
+/ returns:
+/ the number of imported rows
+/ NULL on invalid arguments
+*/
+    int ret;
+    char *path_or_url;
+    char *layer_name;
+    char *table;
+    int swap_axes = 0;
+    int spatial_index = 0;
+    int page_size = -1;
+    char *pk_column = NULL;
+    int rows;
+    sqlite3 *db_handle = sqlite3_context_db_handle (context);
+    GAIA_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
       {
-	  /* exporting the DXF */
-	  gaiaDxfWriter dxf;
-	  gaiaDxfWriterInit (&dxf, out, precision, GAIA_DXF_V12);
-	  ret = gaiaExportDxf (&dxf, db_handle, sql_query, layer_col_name,
-			       geom_col_name, label_col_name,
-			       text_height_col_name, text_rotation_col_name,
-			       geom);
-	  if (ret > 0)
-	      ret = 1;
-	  fclose (out);
+	  sqlite3_result_null (context);
+	  return;
       }
-    sqlite3_result_int (context, ret);
-    if (geom != NULL)
-	gaiaFreeGeomColl (geom);
-    sqlite3_free (path);
+    path_or_url = (char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    layer_name = (char *) sqlite3_value_text (argv[1]);
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+    table = (char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+      {
+	  if (sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      pk_column = (char *) sqlite3_value_text (argv[3]);
+      }
+    if (argc > 4)
+      {
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      swap_axes = sqlite3_value_int (argv[4]);
+      }
+    if (argc > 5)
+      {
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      page_size = sqlite3_value_int (argv[5]);
+      }
+    if (argc > 6)
+      {
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	    {
+		sqlite3_result_null (context);
+		return;
+	    }
+	  else
+	      spatial_index = sqlite3_value_int (argv[6]);
+      }
+
+    ret =
+	load_from_wfs_paged (db_handle, path_or_url, NULL, layer_name,
+			     swap_axes, table, pk_column, spatial_index,
+			     page_size, &rows, NULL, wfs_page_done, NULL);
+
+    if (rows < 0 || !ret)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_int (context, rows);
 }
+#endif /* end including LIBXML2 */
 
 static void
 fnct_CountUnsafeTriggers (sqlite3_context * context, int argc,
@@ -26698,7 +28361,7 @@ fnct_RegisterStyledGroup (sqlite3_context * context, int argc,
 / 0 on failure, -1 on invalid arguments
 */
     int ret;
-    const char *group_name;
+    const char *group_name = NULL;
     const char *f_table_name = NULL;
     const char *f_geometry_column = NULL;
     const char *coverage_name = NULL;
@@ -28249,6 +29912,35 @@ fnct_XB_CacheFlush (sqlite3_context * context, int argc, sqlite3_value ** argv)
 
 #endif /* end including LIBXML2 */
 
+#ifdef LOADABLE_EXTENSION
+static void
+splite_close_callback (void *p_cache)
+{
+/*
+/ the DB connection has been terminated 
+/
+/ this callback function is expected to be invoked only if 
+/ SpatiaLite wasloaded as a dynamic extension and will
+/ perform a final clean-up releasing the internal cache
+/
+*/
+    struct splite_internal_cache *cache =
+	(struct splite_internal_cache *) p_cache;
+
+    if (cache == NULL)
+	return;
+    if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
+	|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
+	return;
+
+#ifdef ENABLE_LWGEOM
+    gaiaResetLwGeomMsg ();
+#endif
+
+    free_internal_cache (cache);
+}
+#endif
+
 SPATIALITE_PRIVATE void *
 register_spatialite_sql_functions (void *p_db, const void *p_cache)
 {
@@ -28256,836 +29948,1343 @@ register_spatialite_sql_functions (void *p_db, const void *p_cache)
     struct splite_internal_cache *cache =
 	(struct splite_internal_cache *) p_cache;
     const char *security_level;
-    sqlite3_create_function (db, "spatialite_version", 0, SQLITE_ANY, 0,
-			     fnct_spatialite_version, 0, 0);
-    sqlite3_create_function (db, "spatialite_target_cpu", 0, SQLITE_ANY, 0,
-			     fnct_spatialite_target_cpu, 0, 0);
-    sqlite3_create_function (db, "proj4_version", 0, SQLITE_ANY, 0,
-			     fnct_proj4_version, 0, 0);
-    sqlite3_create_function (db, "geos_version", 0, SQLITE_ANY, 0,
-			     fnct_geos_version, 0, 0);
-    sqlite3_create_function (db, "lwgeom_version", 0, SQLITE_ANY, 0,
-			     fnct_lwgeom_version, 0, 0);
-    sqlite3_create_function (db, "libxml2_version", 0, SQLITE_ANY, 0,
-			     fnct_libxml2_version, 0, 0);
-    sqlite3_create_function (db, "HasProj", 0, SQLITE_ANY, 0,
-			     fnct_has_proj, 0, 0);
-    sqlite3_create_function (db, "HasGeos", 0, SQLITE_ANY, 0,
-			     fnct_has_geos, 0, 0);
-    sqlite3_create_function (db, "HasGeosAdvanced", 0, SQLITE_ANY, 0,
-			     fnct_has_geos_advanced, 0, 0);
-    sqlite3_create_function (db, "HasGeosTrunk", 0, SQLITE_ANY, 0,
-			     fnct_has_geos_trunk, 0, 0);
-    sqlite3_create_function (db, "HasLwGeom", 0, SQLITE_ANY, 0,
-			     fnct_has_lwgeom, 0, 0);
-    sqlite3_create_function (db, "HasMathSql", 0, SQLITE_ANY, 0,
-			     fnct_has_math_sql, 0, 0);
-    sqlite3_create_function (db, "HasGeoCallbacks", 0, SQLITE_ANY, 0,
-			     fnct_has_geo_callbacks, 0, 0);
-    sqlite3_create_function (db, "HasIconv", 0, SQLITE_ANY, 0,
-			     fnct_has_iconv, 0, 0);
-    sqlite3_create_function (db, "HasFreeXL", 0, SQLITE_ANY, 0,
-			     fnct_has_freeXL, 0, 0);
-    sqlite3_create_function (db, "HasEpsg", 0, SQLITE_ANY, 0,
-			     fnct_has_epsg, 0, 0);
-    sqlite3_create_function (db, "HasLibXML2", 0, SQLITE_ANY, 0,
-			     fnct_has_libxml2, 0, 0);
-    sqlite3_create_function (db, "HasGeoPackage", 0, SQLITE_ANY, 0,
-			     fnct_has_geopackage, 0, 0);
-    sqlite3_create_function (db, "GeometryConstraints", 3, SQLITE_ANY, 0,
-			     fnct_GeometryConstraints, 0, 0);
-    sqlite3_create_function (db, "GeometryConstraints", 4, SQLITE_ANY, 0,
-			     fnct_GeometryConstraints, 0, 0);
-    sqlite3_create_function (db, "RTreeAlign", 3, SQLITE_ANY, 0,
-			     fnct_RTreeAlign, 0, 0);
-    sqlite3_create_function (db, "IsValidNoDataPixel", 3, SQLITE_ANY, 0,
-			     fnct_IsValidNoDataPixel, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterPalette", 2, SQLITE_ANY, 0,
-			     fnct_IsValidRasterPalette, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterStatistics", 2, SQLITE_ANY, 0,
-			     fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterStatistics", 3, SQLITE_ANY, 0,
-			     fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterTile", 4, SQLITE_ANY, 0,
-			     fnct_IsValidRasterTile, 0, 0);
-    sqlite3_create_function (db, "IsPopulatedCoverage", 1, SQLITE_ANY, 0,
-			     fnct_IsPopulatedCoverage, 0, 0);
-    sqlite3_create_function (db, "CheckSpatialMetaData", 0, SQLITE_ANY, 0,
-			     fnct_CheckSpatialMetaData, 0, 0);
-    sqlite3_create_function (db, "CheckGeoPackageMetaData", 0, SQLITE_ANY, 0,
-			     fnct_CheckGeoPackageMetaData, 0, 0);
-    sqlite3_create_function (db, "AutoFDOStart", 0, SQLITE_ANY, 0,
-			     fnct_AutoFDOStart, 0, 0);
-    sqlite3_create_function (db, "AutoFDOStop", 0, SQLITE_ANY, 0,
-			     fnct_AutoFDOStop, 0, 0);
-    sqlite3_create_function (db, "InitFDOSpatialMetaData", 0, SQLITE_ANY, 0,
-			     fnct_InitFDOSpatialMetaData, 0, 0);
-    sqlite3_create_function (db, "AddFDOGeometryColumn", 6, SQLITE_ANY, 0,
-			     fnct_AddFDOGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "RecoverFDOGeometryColumn", 6, SQLITE_ANY, 0,
-			     fnct_RecoverFDOGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "DiscardFDOGeometryColumn", 2, SQLITE_ANY, 0,
-			     fnct_DiscardFDOGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "InitSpatialMetaData", 0, SQLITE_ANY, 0,
-			     fnct_InitSpatialMetaData, 0, 0);
-    sqlite3_create_function (db, "InitSpatialMetaData", 1, SQLITE_ANY, 0,
-			     fnct_InitSpatialMetaData, 0, 0);
-    sqlite3_create_function (db, "InitSpatialMetaData", 2, SQLITE_ANY, 0,
-			     fnct_InitSpatialMetaData, 0, 0);
-    sqlite3_create_function (db, "InsertEpsgSrid", 1, SQLITE_ANY, 0,
-			     fnct_InsertEpsgSrid, 0, 0);
-    sqlite3_create_function (db, "AddGeometryColumn", 4, SQLITE_ANY, 0,
-			     fnct_AddGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "AddGeometryColumn", 5, SQLITE_ANY, 0,
-			     fnct_AddGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "AddGeometryColumn", 6, SQLITE_ANY, 0,
-			     fnct_AddGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "RecoverGeometryColumn", 4, SQLITE_ANY, 0,
-			     fnct_RecoverGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "RecoverGeometryColumn", 5, SQLITE_ANY, 0,
-			     fnct_RecoverGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "DiscardGeometryColumn", 2, SQLITE_ANY, 0,
-			     fnct_DiscardGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "RegisterVirtualGeometry", 1, SQLITE_ANY, 0,
-			     fnct_RegisterVirtualGeometry, 0, 0);
-    sqlite3_create_function (db, "DropVirtualGeometry", 1, SQLITE_ANY, 0,
-			     fnct_DropVirtualGeometry, 0, 0);
-    sqlite3_create_function (db, "RecoverSpatialIndex", 0, SQLITE_ANY, 0,
-			     fnct_RecoverSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "RecoverSpatialIndex", 1, SQLITE_ANY, 0,
-			     fnct_RecoverSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "RecoverSpatialIndex", 2, SQLITE_ANY, 0,
-			     fnct_RecoverSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "RecoverSpatialIndex", 3, SQLITE_ANY, 0,
-			     fnct_RecoverSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "CheckSpatialIndex", 0, SQLITE_ANY, 0,
-			     fnct_CheckSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "CheckSpatialIndex", 2, SQLITE_ANY, 0,
-			     fnct_CheckSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "CheckShadowedRowid", 1, SQLITE_ANY, 0,
-			     fnct_CheckShadowedRowid, 0, 0);
-    sqlite3_create_function (db, "CheckWithoutRowid", 1, SQLITE_ANY, 0,
-			     fnct_CheckWithoutRowid, 0, 0);
-    sqlite3_create_function (db, "CreateSpatialIndex", 2, SQLITE_ANY, 0,
-			     fnct_CreateSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "CreateMbrCache", 2, SQLITE_ANY, 0,
-			     fnct_CreateMbrCache, 0, 0);
-    sqlite3_create_function (db, "DisableSpatialIndex", 2, SQLITE_ANY, 0,
-			     fnct_DisableSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "RebuildGeometryTriggers", 2, SQLITE_ANY, 0,
-			     fnct_RebuildGeometryTriggers, 0, 0);
-    sqlite3_create_function (db, "UpdateLayerStatistics", 0, SQLITE_ANY, 0,
-			     fnct_UpdateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "UpdateLayerStatistics", 1, SQLITE_ANY, 0,
-			     fnct_UpdateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "UpdateLayerStatistics", 2, SQLITE_ANY, 0,
-			     fnct_UpdateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "GetLayerExtent", 1, SQLITE_ANY, 0,
-			     fnct_GetLayerExtent, 0, 0);
-    sqlite3_create_function (db, "GetLayerExtent", 2, SQLITE_ANY, 0,
-			     fnct_GetLayerExtent, 0, 0);
-    sqlite3_create_function (db, "GetLayerExtent", 3, SQLITE_ANY, 0,
-			     fnct_GetLayerExtent, 0, 0);
-    sqlite3_create_function (db, "InvalidateLayerStatistics", 0, SQLITE_ANY, 0,
-			     fnct_InvalidateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "InvalidateLayerStatistics", 1, SQLITE_ANY, 0,
-			     fnct_InvalidateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "InvalidateLayerStatistics", 2, SQLITE_ANY, 0,
-			     fnct_InvalidateLayerStatistics, 0, 0);
-    sqlite3_create_function (db, "CreateRasterCoveragesTable", 0, SQLITE_ANY,
-			     0, fnct_CreateRasterCoveragesTable, 0, 0);
-    sqlite3_create_function (db, "CreateMetaCatalogTables", 1, SQLITE_ANY, 0,
-			     fnct_CreateMetaCatalogTables, 0, 0);
-    sqlite3_create_function (db, "UpdateMetaCatalogStatistics", 3, SQLITE_ANY,
-			     0, fnct_UpdateMetaCatalogStatistics, 0, 0);
-    sqlite3_create_function (db, "UpdateMetaCatalogStatistics", 4, SQLITE_ANY,
-			     0, fnct_UpdateMetaCatalogStatistics, 0, 0);
-    sqlite3_create_function (db, "AsText", 1, SQLITE_ANY, 0, fnct_AsText, 0, 0);
-    sqlite3_create_function (db, "ST_AsText", 1, SQLITE_ANY, 0, fnct_AsText, 0,
-			     0);
-    sqlite3_create_function (db, "AsWkt", 1, SQLITE_ANY, 0, fnct_AsWkt, 0, 0);
-    sqlite3_create_function (db, "AsWkt", 2, SQLITE_ANY, 0, fnct_AsWkt, 0, 0);
-    sqlite3_create_function (db, "AsSvg", 1, SQLITE_ANY, 0, fnct_AsSvg1, 0, 0);
-    sqlite3_create_function (db, "AsSvg", 2, SQLITE_ANY, 0, fnct_AsSvg2, 0, 0);
-    sqlite3_create_function (db, "AsSvg", 3, SQLITE_ANY, 0, fnct_AsSvg3, 0, 0);
+
+#ifdef LOADABLE_EXTENSION
+/* registering the CLOSE-CALLBACK function */
+    sqlite3_create_function_v2 (db, "spatialite_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_spatialite_version, 0, 0,
+				splite_close_callback);
+#else
+    sqlite3_create_function_v2 (db, "spatialite_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_spatialite_version, 0, 0, 0);
+#endif
+
+    sqlite3_create_function_v2 (db, "spatialite_target_cpu", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_spatialite_target_cpu, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "proj4_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_proj4_version, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "geos_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_geos_version, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "lwgeom_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_lwgeom_version, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "libxml2_version", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_libxml2_version, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasProj", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_proj, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasGeos", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_geos, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasGeosAdvanced", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_geos_advanced, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasGeosTrunk", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_geos_trunk, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasLwGeom", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_lwgeom, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasMathSql", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_math_sql, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasGeoCallbacks", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_geo_callbacks, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasIconv", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_iconv, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasFreeXL", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_freeXL, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasEpsg", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_epsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasLibXML2", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_libxml2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HasGeoPackage", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_has_geopackage, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryConstraints", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryConstraints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryConstraints", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryConstraints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RTreeAlign", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RTreeAlign, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidNoDataPixel", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidNoDataPixel, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidRasterPalette", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidRasterPalette, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidRasterStatistics", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidRasterStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidRasterStatistics", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidRasterStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidRasterTile", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidRasterTile, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsPopulatedCoverage", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsPopulatedCoverage, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckSpatialMetaData", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckSpatialMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckGeoPackageMetaData", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckGeoPackageMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AutoFDOStart", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AutoFDOStart, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AutoFDOStop", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AutoFDOStop, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InitFDOSpatialMetaData", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InitFDOSpatialMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddFDOGeometryColumn", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddFDOGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverFDOGeometryColumn", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverFDOGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DiscardFDOGeometryColumn", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DiscardFDOGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InitSpatialMetaData", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InitSpatialMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InitSpatialMetaData", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InitSpatialMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InitSpatialMetaData", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InitSpatialMetaData, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InsertEpsgSrid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InsertEpsgSrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddGeometryColumn", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddGeometryColumn", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddGeometryColumn", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverGeometryColumn", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverGeometryColumn", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpgradeGeometryTriggers", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpgradeGeometryTriggers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DiscardGeometryColumn", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DiscardGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterVirtualGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterVirtualGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DropVirtualGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DropVirtualGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverSpatialIndex", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverSpatialIndex", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverSpatialIndex", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RecoverSpatialIndex", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RecoverSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckSpatialIndex", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckSpatialIndex", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckShadowedRowid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckShadowedRowid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckWithoutRowid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckWithoutRowid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateSpatialIndex", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateMbrCache", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateMbrCache, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DisableSpatialIndex", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DisableSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RebuildGeometryTriggers", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RebuildGeometryTriggers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpdateLayerStatistics", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpdateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpdateLayerStatistics", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpdateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpdateLayerStatistics", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpdateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GetLayerExtent", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GetLayerExtent, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GetLayerExtent", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GetLayerExtent, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GetLayerExtent", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GetLayerExtent, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InvalidateLayerStatistics", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InvalidateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InvalidateLayerStatistics", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InvalidateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InvalidateLayerStatistics", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InvalidateLayerStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateRasterCoveragesTable", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateRasterCoveragesTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateMetaCatalogTables", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateMetaCatalogTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpdateMetaCatalogStatistics", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpdateMetaCatalogStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UpdateMetaCatalogStatistics", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UpdateMetaCatalogStatistics, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsText, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsText, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsWkt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsWkt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsWkt", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsWkt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsSvg", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsSvg1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsSvg", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsSvg2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsSvg", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsSvg3, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 8,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 9,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 10,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 11,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 12,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 13,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CloneTable", 14,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CloneTable, 0, 0, 0);
 
 #ifndef OMIT_PROJ		/* PROJ.4 is strictly required to support KML */
-    sqlite3_create_function (db, "AsKml", 1, SQLITE_ANY, cache, fnct_AsKml, 0,
-			     0);
-    sqlite3_create_function (db, "AsKml", 2, SQLITE_ANY, cache, fnct_AsKml, 0,
-			     0);
-    sqlite3_create_function (db, "AsKml", 3, SQLITE_ANY, cache, fnct_AsKml, 0,
-			     0);
-    sqlite3_create_function (db, "AsKml", 4, SQLITE_ANY, cache, fnct_AsKml, 0,
-			     0);
+    sqlite3_create_function_v2 (db, "AsKml", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_AsKml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsKml", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_AsKml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsKml", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_AsKml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsKml", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_AsKml, 0, 0, 0);
 #endif /* end including PROJ.4 */
 
-    sqlite3_create_function (db, "AsGml", 1, SQLITE_ANY, 0, fnct_AsGml, 0, 0);
-    sqlite3_create_function (db, "AsGml", 2, SQLITE_ANY, 0, fnct_AsGml, 0, 0);
-    sqlite3_create_function (db, "AsGml", 3, SQLITE_ANY, 0, fnct_AsGml, 0, 0);
-    sqlite3_create_function (db, "GeomFromGml", 1, SQLITE_ANY, cache,
-			     fnct_FromGml, 0, 0);
-    sqlite3_create_function (db, "AsGeoJSON", 1, SQLITE_ANY, 0,
-			     fnct_AsGeoJSON, 0, 0);
-    sqlite3_create_function (db, "AsGeoJSON", 2, SQLITE_ANY, 0,
-			     fnct_AsGeoJSON, 0, 0);
-    sqlite3_create_function (db, "AsGeoJSON", 3, SQLITE_ANY, 0,
-			     fnct_AsGeoJSON, 0, 0);
-    sqlite3_create_function (db, "GeomFromGeoJSON", 1, SQLITE_ANY, 0,
-			     fnct_FromGeoJSON, 0, 0);
-    sqlite3_create_function (db, "GeomFromKml", 1, SQLITE_ANY, 0,
-			     fnct_FromKml, 0, 0);
-    sqlite3_create_function (db, "AsFGF", 2, SQLITE_ANY, 0, fnct_AsFGF, 0, 0);
-    sqlite3_create_function (db, "GeomFromEWKB", 1, SQLITE_ANY, 0,
-			     fnct_FromEWKB, 0, 0);
-    sqlite3_create_function (db, "AsEWKB", 1, SQLITE_ANY, 0, fnct_ToEWKB, 0, 0);
-    sqlite3_create_function (db, "AsEWKT", 1, SQLITE_ANY, 0, fnct_ToEWKT, 0, 0);
-    sqlite3_create_function (db, "GeomFromEWKT", 1, SQLITE_ANY, 0,
-			     fnct_FromEWKT, 0, 0);
-    sqlite3_create_function (db, "AsBinary", 1, SQLITE_ANY, 0, fnct_AsBinary,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AsBinary", 1, SQLITE_ANY, 0,
-			     fnct_AsBinary, 0, 0);
-    sqlite3_create_function (db, "GeomFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromText1, 0, 0);
-    sqlite3_create_function (db, "GeomFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromText2, 0, 0);
-    sqlite3_create_function (db, "GeometryFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromText1, 0, 0);
-    sqlite3_create_function (db, "GeometryFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromText2, 0, 0);
-    sqlite3_create_function (db, "GeomCollFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomCollFromText1, 0, 0);
-    sqlite3_create_function (db, "GeomCollFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomCollFromText2, 0, 0);
-    sqlite3_create_function (db, "GeometryCollectionFromText", 1, SQLITE_ANY,
-			     0, fnct_GeomCollFromText1, 0, 0);
-    sqlite3_create_function (db, "GeometryCollectionFromText", 2, SQLITE_ANY,
-			     0, fnct_GeomCollFromText2, 0, 0);
-    sqlite3_create_function (db, "PointFromText", 1, SQLITE_ANY, 0,
-			     fnct_PointFromText1, 0, 0);
-    sqlite3_create_function (db, "PointFromText", 2, SQLITE_ANY, 0,
-			     fnct_PointFromText2, 0, 0);
-    sqlite3_create_function (db, "LineFromText", 1, SQLITE_ANY, 0,
-			     fnct_LineFromText1, 0, 0);
-    sqlite3_create_function (db, "LineFromText", 2, SQLITE_ANY, 0,
-			     fnct_LineFromText2, 0, 0);
-    sqlite3_create_function (db, "LineStringFromText", 1, SQLITE_ANY, 0,
-			     fnct_LineFromText1, 0, 0);
-    sqlite3_create_function (db, "LineStringFromText", 2, SQLITE_ANY, 0,
-			     fnct_LineFromText2, 0, 0);
-    sqlite3_create_function (db, "PolyFromText", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromText1, 0, 0);
-    sqlite3_create_function (db, "PolyFromText", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromText2, 0, 0);
-    sqlite3_create_function (db, "PolygonFromText", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromText1, 0, 0);
-    sqlite3_create_function (db, "PolygonFromText", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromText2, 0, 0);
-    sqlite3_create_function (db, "MPointFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromText1, 0, 0);
-    sqlite3_create_function (db, "MPointFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromText2, 0, 0);
-    sqlite3_create_function (db, "MultiPointFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromText1, 0, 0);
-    sqlite3_create_function (db, "MultiPointFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromText2, 0, 0);
-    sqlite3_create_function (db, "MLineFromText", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromText1, 0, 0);
-    sqlite3_create_function (db, "MLineFromText", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromText2, 0, 0);
-    sqlite3_create_function (db, "MultiLineStringFromText", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromText1, 0, 0);
-    sqlite3_create_function (db, "MultiLineStringFromText", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromText2, 0, 0);
-    sqlite3_create_function (db, "MPolyFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "MPolyFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "MultiPolygonFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "MultiPolygonFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "GeomFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb1, 0, 0);
-    sqlite3_create_function (db, "GeomFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb2, 0, 0);
-    sqlite3_create_function (db, "GeometryFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb1, 0, 0);
-    sqlite3_create_function (db, "GeometryFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb2, 0, 0);
-    sqlite3_create_function (db, "GeomCollFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb1, 0, 0);
-    sqlite3_create_function (db, "GeomCollFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb2, 0, 0);
-    sqlite3_create_function (db, "GeometryCollectionFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb1, 0, 0);
-    sqlite3_create_function (db, "GeometryCollectionFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb2, 0, 0);
-    sqlite3_create_function (db, "PointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "PointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "LineFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_LineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "LineFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_LineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "LineStringFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_LineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "LineStringFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_LineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "PolyFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "PolyFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "PolygonFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "PolygonFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MPointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MPointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MultiPointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MultiPointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MLineFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MLineFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MultiLineStringFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MultiLineStringFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MPolyFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MPolyFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "MultiPolygonFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "MultiPolygonFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_WKTToSQL", 1, SQLITE_ANY, 0,
-			     fnct_WktToSql, 0, 0);
-    sqlite3_create_function (db, "ST_GeomFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_GeomFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_GeomCollFromText", 1, SQLITE_ANY, 0,
-			     fnct_GeomCollFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_GeomCollFromText", 2, SQLITE_ANY, 0,
-			     fnct_GeomCollFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryCollectionFromText", 1,
-			     SQLITE_ANY, 0, fnct_GeomCollFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryCollectionFromText", 2,
-			     SQLITE_ANY, 0, fnct_GeomCollFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_PointFromText", 1, SQLITE_ANY, 0,
-			     fnct_PointFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_PointFromText", 2, SQLITE_ANY, 0,
-			     fnct_PointFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_LineFromText", 1, SQLITE_ANY, 0,
-			     fnct_LineFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_LineFromText", 2, SQLITE_ANY, 0,
-			     fnct_LineFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_LineStringFromText", 1, SQLITE_ANY, 0,
-			     fnct_LineFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_LineStringFromText", 2, SQLITE_ANY, 0,
-			     fnct_LineFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_PolyFromText", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_PolyFromText", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_PolygonFromText", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_PolygonFromText", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MPointFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MPointFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPointFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPointFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MLineFromText", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MLineFromText", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiLineStringFromText", 1, SQLITE_ANY,
-			     0, fnct_MLineFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiLineStringFromText", 2, SQLITE_ANY,
-			     0, fnct_MLineFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MPolyFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MPolyFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPolygonFromText", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPolygonFromText", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_WKBToSQL", 1, SQLITE_ANY, 0,
-			     fnct_WkbToSql, 0, 0);
-    sqlite3_create_function (db, "ST_GeomFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_GeomFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_GeomCollFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_GeomCollFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_GeomCollFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryCollectionFromWKB", 1, SQLITE_ANY,
-			     0, fnct_GeomCollFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryCollectionFromWKB", 2, SQLITE_ANY,
-			     0, fnct_GeomCollFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_PointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_PointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_LineFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_LineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_LineFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_LineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_LineStringFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_LineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_LineStringFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_LineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_PolyFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_PolyFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_PolygonFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_PolygonFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_PolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MPointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MPointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPointFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPointFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPointFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MLineFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MLineFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiLineStringFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiLineStringFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MLineFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MPolyFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MPolyFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPolygonFromWKB", 1, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb1, 0, 0);
-    sqlite3_create_function (db, "ST_MultiPolygonFromWKB", 2, SQLITE_ANY, 0,
-			     fnct_MPolyFromWkb2, 0, 0);
-    sqlite3_create_function (db, "GeomFromFGF", 1, SQLITE_ANY, 0,
-			     fnct_GeometryFromFGF1, 0, 0);
-    sqlite3_create_function (db, "GeomFromFGF", 2, SQLITE_ANY, 0,
-			     fnct_GeometryFromFGF2, 0, 0);
-    sqlite3_create_function (db, "CompressGeometry", 1, SQLITE_ANY, 0,
-			     fnct_CompressGeometry, 0, 0);
-    sqlite3_create_function (db, "UncompressGeometry", 1, SQLITE_ANY, 0,
-			     fnct_UncompressGeometry, 0, 0);
-    sqlite3_create_function (db, "SanitizeGeometry", 1, SQLITE_ANY, 0,
-			     fnct_SanitizeGeometry, 0, 0);
-    sqlite3_create_function (db, "CastToInteger", 1, SQLITE_ANY, 0,
-			     fnct_CastToInteger, 0, 0);
-    sqlite3_create_function (db, "CastToDouble", 1, SQLITE_ANY, 0,
-			     fnct_CastToDouble, 0, 0);
-    sqlite3_create_function (db, "CastToText", 1, SQLITE_ANY, 0,
-			     fnct_CastToText, 0, 0);
-    sqlite3_create_function (db, "CastToText", 2, SQLITE_ANY, 0,
-			     fnct_CastToText, 0, 0);
-    sqlite3_create_function (db, "CastToBlob", 1, SQLITE_ANY, 0,
-			     fnct_CastToBlob, 0, 0);
-    sqlite3_create_function (db, "CastToBlob", 2, SQLITE_ANY, 0,
-			     fnct_CastToBlob, 0, 0);
-    sqlite3_create_function (db, "ForceAsNull", 2, SQLITE_ANY, 0,
-			     fnct_ForceAsNull, 0, 0);
-    sqlite3_create_function (db, "CreateUUID", 0, SQLITE_ANY, 0,
-			     fnct_CreateUUID, 0, 0);
-    sqlite3_create_function (db, "MD5Checksum", 1, SQLITE_ANY, 0,
-			     fnct_MD5Checksum, 0, 0);
-    sqlite3_create_function (db, "MD5TotalChecksum", 1, SQLITE_ANY, 0, 0,
-			     fnct_MD5TotalChecksum_step,
-			     fnct_MD5TotalChecksum_final);
-    sqlite3_create_function (db, "CastToPoint", 1, SQLITE_ANY, 0,
-			     fnct_CastToPoint, 0, 0);
-    sqlite3_create_function (db, "CastToLinestring", 1, SQLITE_ANY, 0,
-			     fnct_CastToLinestring, 0, 0);
-    sqlite3_create_function (db, "CastToPolygon", 1, SQLITE_ANY, 0,
-			     fnct_CastToPolygon, 0, 0);
-    sqlite3_create_function (db, "CastToMultiPoint", 1, SQLITE_ANY, 0,
-			     fnct_CastToMultiPoint, 0, 0);
-    sqlite3_create_function (db, "CastToMultiLinestring", 1, SQLITE_ANY, 0,
-			     fnct_CastToMultiLinestring, 0, 0);
-    sqlite3_create_function (db, "CastToMultiPolygon", 1, SQLITE_ANY, 0,
-			     fnct_CastToMultiPolygon, 0, 0);
-    sqlite3_create_function (db, "CastToGeometryCollection", 1, SQLITE_ANY, 0,
-			     fnct_CastToGeometryCollection, 0, 0);
-    sqlite3_create_function (db, "CastToMulti", 1, SQLITE_ANY, 0,
-			     fnct_CastToMulti, 0, 0);
-    sqlite3_create_function (db, "ST_Multi", 1, SQLITE_ANY, 0,
-			     fnct_CastToMulti, 0, 0);
-    sqlite3_create_function (db, "CastToSingle", 1, SQLITE_ANY, 0,
-			     fnct_CastToSingle, 0, 0);
-    sqlite3_create_function (db, "CastToXY", 1, SQLITE_ANY, 0, fnct_CastToXY,
-			     0, 0);
-    sqlite3_create_function (db, "CastToXYZ", 1, SQLITE_ANY, 0, fnct_CastToXYZ,
-			     0, 0);
-    sqlite3_create_function (db, "CastToXYM", 1, SQLITE_ANY, 0, fnct_CastToXYM,
-			     0, 0);
-    sqlite3_create_function (db, "CastToXYZM", 1, SQLITE_ANY, 0,
-			     fnct_CastToXYZM, 0, 0);
-    sqlite3_create_function (db, "ExtractMultiPoint", 1, SQLITE_ANY, 0,
-			     fnct_ExtractMultiPoint, 0, 0);
-    sqlite3_create_function (db, "ExtractMultiLinestring", 1, SQLITE_ANY, 0,
-			     fnct_ExtractMultiLinestring, 0, 0);
-    sqlite3_create_function (db, "ExtractMultiPolygon", 1, SQLITE_ANY, 0,
-			     fnct_ExtractMultiPolygon, 0, 0);
-    sqlite3_create_function (db, "ST_Reverse", 1, SQLITE_ANY, 0, fnct_Reverse,
-			     0, 0);
-    sqlite3_create_function (db, "ST_ForceLHR", 1, SQLITE_ANY, 0,
-			     fnct_ForceLHR, 0, 0);
-    sqlite3_create_function (db, "Dimension", 1, SQLITE_ANY, 0, fnct_Dimension,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Dimension", 1, SQLITE_ANY, 0,
-			     fnct_Dimension, 0, 0);
-    sqlite3_create_function (db, "CoordDimension", 1, SQLITE_ANY, 0,
-			     fnct_CoordDimension, 0, 0);
-    sqlite3_create_function (db, "ST_NDims", 1, SQLITE_ANY, 0, fnct_NDims, 0,
-			     0);
-    sqlite3_create_function (db, "GeometryType", 1, SQLITE_ANY, 0,
-			     fnct_GeometryType, 0, 0);
-    sqlite3_create_function (db, "ST_GeometryType", 1, SQLITE_ANY, 0,
-			     fnct_GeometryType, 0, 0);
-    sqlite3_create_function (db, "GeometryAliasType", 1, SQLITE_ANY, 0,
-			     fnct_GeometryAliasType, 0, 0);
-    sqlite3_create_function (db, "SridFromAuthCRS", 2, SQLITE_ANY, 0,
-			     fnct_SridFromAuthCRS, 0, 0);
-    sqlite3_create_function (db, "SRID", 1, SQLITE_ANY, 0, fnct_SRID, 0, 0);
-    sqlite3_create_function (db, "ST_SRID", 1, SQLITE_ANY, 0, fnct_SRID, 0, 0);
-    sqlite3_create_function (db, "SetSRID", 2, SQLITE_ANY, 0, fnct_SetSRID, 0,
-			     0);
-    sqlite3_create_function (db, "IsEmpty", 1, SQLITE_ANY, 0, fnct_IsEmpty, 0,
-			     0);
-    sqlite3_create_function (db, "ST_IsEmpty", 1, SQLITE_ANY, 0, fnct_IsEmpty,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Is3D", 1, SQLITE_ANY, 0, fnct_Is3D, 0, 0);
-    sqlite3_create_function (db, "ST_IsMeasured", 1, SQLITE_ANY, 0,
-			     fnct_IsMeasured, 0, 0);
-    sqlite3_create_function (db, "Envelope", 1, SQLITE_ANY, 0, fnct_Envelope,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Envelope", 1, SQLITE_ANY, 0,
-			     fnct_Envelope, 0, 0);
-    sqlite3_create_function (db, "ST_Expand", 2, SQLITE_ANY, 0, fnct_Expand,
-			     0, 0);
-    sqlite3_create_function (db, "X", 1, SQLITE_ANY, 0, fnct_X, 0, 0);
-    sqlite3_create_function (db, "Y", 1, SQLITE_ANY, 0, fnct_Y, 0, 0);
-    sqlite3_create_function (db, "Z", 1, SQLITE_ANY, 0, fnct_Z, 0, 0);
-    sqlite3_create_function (db, "M", 1, SQLITE_ANY, 0, fnct_M, 0, 0);
-    sqlite3_create_function (db, "ST_X", 1, SQLITE_ANY, 0, fnct_X, 0, 0);
-    sqlite3_create_function (db, "ST_Y", 1, SQLITE_ANY, 0, fnct_Y, 0, 0);
-    sqlite3_create_function (db, "ST_Z", 1, SQLITE_ANY, 0, fnct_Z, 0, 0);
-    sqlite3_create_function (db, "ST_M", 1, SQLITE_ANY, 0, fnct_M, 0, 0);
-    sqlite3_create_function (db, "ST_MinX", 1, SQLITE_ANY, 0, fnct_MbrMinX, 0,
-			     0);
-    sqlite3_create_function (db, "ST_MinY", 1, SQLITE_ANY, 0, fnct_MbrMinY, 0,
-			     0);
-    sqlite3_create_function (db, "ST_MinZ", 1, SQLITE_ANY, 0, fnct_MinZ, 0, 0);
-    sqlite3_create_function (db, "ST_MinM", 1, SQLITE_ANY, 0, fnct_MinM, 0, 0);
-    sqlite3_create_function (db, "ST_MaxX", 1, SQLITE_ANY, 0, fnct_MbrMaxX, 0,
-			     0);
-    sqlite3_create_function (db, "ST_MaxY", 1, SQLITE_ANY, 0, fnct_MbrMaxY, 0,
-			     0);
-    sqlite3_create_function (db, "ST_MaxZ", 1, SQLITE_ANY, 0, fnct_MaxZ, 0, 0);
-    sqlite3_create_function (db, "ST_MaxM", 1, SQLITE_ANY, 0, fnct_MaxM, 0, 0);
-    sqlite3_create_function (db, "NumPoints", 1, SQLITE_ANY, 0,
-			     fnct_NumPoints, 0, 0);
-    sqlite3_create_function (db, "ST_NumPoints", 1, SQLITE_ANY, 0,
-			     fnct_NumPoints, 0, 0);
-    sqlite3_create_function (db, "StartPoint", 1, SQLITE_ANY, 0,
-			     fnct_StartPoint, 0, 0);
-    sqlite3_create_function (db, "EndPoint", 1, SQLITE_ANY, 0, fnct_EndPoint,
-			     0, 0);
-    sqlite3_create_function (db, "ST_StartPoint", 1, SQLITE_ANY, 0,
-			     fnct_StartPoint, 0, 0);
-    sqlite3_create_function (db, "ST_EndPoint", 1, SQLITE_ANY, 0,
-			     fnct_EndPoint, 0, 0);
-    sqlite3_create_function (db, "PointN", 2, SQLITE_ANY, 0, fnct_PointN, 0, 0);
-    sqlite3_create_function (db, "ST_PointN", 2, SQLITE_ANY, 0, fnct_PointN, 0,
-			     0);
-    sqlite3_create_function (db, "ExteriorRing", 1, SQLITE_ANY, 0,
-			     fnct_ExteriorRing, 0, 0);
-    sqlite3_create_function (db, "ST_ExteriorRing", 1, SQLITE_ANY, 0,
-			     fnct_ExteriorRing, 0, 0);
-    sqlite3_create_function (db, "NumInteriorRing", 1, SQLITE_ANY, 0,
-			     fnct_NumInteriorRings, 0, 0);
-    sqlite3_create_function (db, "NumInteriorRings", 1, SQLITE_ANY, 0,
-			     fnct_NumInteriorRings, 0, 0);
-    sqlite3_create_function (db, "ST_NumInteriorRing", 1, SQLITE_ANY, 0,
-			     fnct_NumInteriorRings, 0, 0);
-    sqlite3_create_function (db, "InteriorRingN", 2, SQLITE_ANY, 0,
-			     fnct_InteriorRingN, 0, 0);
-    sqlite3_create_function (db, "ST_InteriorRingN", 2, SQLITE_ANY, 0,
-			     fnct_InteriorRingN, 0, 0);
-    sqlite3_create_function (db, "NumGeometries", 1, SQLITE_ANY, 0,
-			     fnct_NumGeometries, 0, 0);
-    sqlite3_create_function (db, "ST_NumGeometries", 1, SQLITE_ANY, 0,
-			     fnct_NumGeometries, 0, 0);
-    sqlite3_create_function (db, "GeometryN", 2, SQLITE_ANY, 0, fnct_GeometryN,
-			     0, 0);
-    sqlite3_create_function (db, "ST_GeometryN", 2, SQLITE_ANY, 0,
-			     fnct_GeometryN, 0, 0);
-    sqlite3_create_function (db, "MBRContains", 2, SQLITE_ANY, 0,
-			     fnct_MbrContains, 0, 0);
-    sqlite3_create_function (db, "MbrDisjoint", 2, SQLITE_ANY, 0,
-			     fnct_MbrDisjoint, 0, 0);
-    sqlite3_create_function (db, "MBREqual", 2, SQLITE_ANY, 0, fnct_MbrEqual,
-			     0, 0);
-    sqlite3_create_function (db, "MbrIntersects", 2, SQLITE_ANY, 0,
-			     fnct_MbrIntersects, 0, 0);
-    sqlite3_create_function (db, "ST_EnvIntersects", 2, SQLITE_ANY, 0,
-			     fnct_MbrIntersects, 0, 0);
-    sqlite3_create_function (db, "ST_EnvIntersects", 5, SQLITE_ANY, 0,
-			     fnct_EnvIntersects, 0, 0);
-    sqlite3_create_function (db, "ST_EnvelopesIntersects", 2, SQLITE_ANY, 0,
-			     fnct_MbrIntersects, 0, 0);
-    sqlite3_create_function (db, "ST_EnvelopesIntersects", 5, SQLITE_ANY, 0,
-			     fnct_EnvIntersects, 0, 0);
-    sqlite3_create_function (db, "MBROverlaps", 2, SQLITE_ANY, 0,
-			     fnct_MbrOverlaps, 0, 0);
-    sqlite3_create_function (db, "MbrTouches", 2, SQLITE_ANY, 0,
-			     fnct_MbrTouches, 0, 0);
-    sqlite3_create_function (db, "MbrWithin", 2, SQLITE_ANY, 0, fnct_MbrWithin,
-			     0, 0);
-    sqlite3_create_function (db, "ShiftCoords", 3, SQLITE_ANY, 0,
-			     fnct_ShiftCoords, 0, 0);
-    sqlite3_create_function (db, "ShiftCoordinates", 3, SQLITE_ANY, 0,
-			     fnct_ShiftCoords, 0, 0);
-    sqlite3_create_function (db, "ST_Translate", 4, SQLITE_ANY, 0,
-			     fnct_Translate, 0, 0);
-    sqlite3_create_function (db, "ST_Shift_Longitude", 1, SQLITE_ANY, 0,
-			     fnct_ShiftLongitude, 0, 0);
-    sqlite3_create_function (db, "NormalizeLonLat", 1, SQLITE_ANY, 0,
-			     fnct_NormalizeLonLat, 0, 0);
-    sqlite3_create_function (db, "ScaleCoords", 2, SQLITE_ANY, 0,
-			     fnct_ScaleCoords, 0, 0);
-    sqlite3_create_function (db, "ScaleCoordinates", 2, SQLITE_ANY, 0,
-			     fnct_ScaleCoords, 0, 0);
-    sqlite3_create_function (db, "ScaleCoords", 3, SQLITE_ANY, 0,
-			     fnct_ScaleCoords, 0, 0);
-    sqlite3_create_function (db, "ScaleCoordinates", 3, SQLITE_ANY, 0,
-			     fnct_ScaleCoords, 0, 0);
-    sqlite3_create_function (db, "RotateCoords", 2, SQLITE_ANY, 0,
-			     fnct_RotateCoords, 0, 0);
-    sqlite3_create_function (db, "RotateCoordinates", 2, SQLITE_ANY, 0,
-			     fnct_RotateCoords, 0, 0);
-    sqlite3_create_function (db, "ReflectCoords", 3, SQLITE_ANY, 0,
-			     fnct_ReflectCoords, 0, 0);
-    sqlite3_create_function (db, "ReflectCoordinates", 3, SQLITE_ANY, 0,
-			     fnct_ReflectCoords, 0, 0);
-    sqlite3_create_function (db, "SwapCoords", 1, SQLITE_ANY, 0,
-			     fnct_SwapCoords, 0, 0);
-    sqlite3_create_function (db, "SwapCoordinates", 1, SQLITE_ANY, 0,
-			     fnct_SwapCoords, 0, 0);
-    sqlite3_create_function (db, "BuildMbr", 4, SQLITE_ANY, 0, fnct_BuildMbr1,
-			     0, 0);
-    sqlite3_create_function (db, "BuildMbr", 5, SQLITE_ANY, 0, fnct_BuildMbr2,
-			     0, 0);
-    sqlite3_create_function (db, "BuildCircleMbr", 3, SQLITE_ANY, 0,
-			     fnct_BuildCircleMbr1, 0, 0);
-    sqlite3_create_function (db, "BuildCircleMbr", 4, SQLITE_ANY, 0,
-			     fnct_BuildCircleMbr2, 0, 0);
-    sqlite3_create_function (db, "Extent", 1, SQLITE_ANY, 0, 0,
-			     fnct_Extent_step, fnct_Extent_final);
-    sqlite3_create_function (db, "MbrMinX", 1, SQLITE_ANY, 0, fnct_MbrMinX, 0,
-			     0);
-    sqlite3_create_function (db, "MbrMaxX", 1, SQLITE_ANY, 0, fnct_MbrMaxX, 0,
-			     0);
-    sqlite3_create_function (db, "MbrMinY", 1, SQLITE_ANY, 0, fnct_MbrMinY, 0,
-			     0);
-    sqlite3_create_function (db, "MbrMaxY", 1, SQLITE_ANY, 0, fnct_MbrMaxY, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Point", 2, SQLITE_ANY, 0, fnct_MakePoint1,
-			     0, 0);
-    sqlite3_create_function (db, "MakePoint", 2, SQLITE_ANY, 0,
-			     fnct_MakePoint1, 0, 0);
-    sqlite3_create_function (db, "MakePoint", 3, SQLITE_ANY, 0,
-			     fnct_MakePoint2, 0, 0);
-    sqlite3_create_function (db, "MakePointZ", 3, SQLITE_ANY, 0,
-			     fnct_MakePointZ1, 0, 0);
-    sqlite3_create_function (db, "MakePointZ", 4, SQLITE_ANY, 0,
-			     fnct_MakePointZ2, 0, 0);
-    sqlite3_create_function (db, "MakePointM", 3, SQLITE_ANY, 0,
-			     fnct_MakePointM1, 0, 0);
-    sqlite3_create_function (db, "MakePointM", 4, SQLITE_ANY, 0,
-			     fnct_MakePointM2, 0, 0);
-    sqlite3_create_function (db, "MakePointZM", 4, SQLITE_ANY, 0,
-			     fnct_MakePointZM1, 0, 0);
-    sqlite3_create_function (db, "MakePointZM", 5, SQLITE_ANY, 0,
-			     fnct_MakePointZM2, 0, 0);
-    sqlite3_create_function (db, "MakeLine", 1, SQLITE_ANY, 0, 0,
-			     fnct_MakeLine_step, fnct_MakeLine_final);
-    sqlite3_create_function (db, "MakeLine", 2, SQLITE_ANY, 0, fnct_MakeLine,
-			     0, 0);
-    sqlite3_create_function (db, "MakeCircle", 3, SQLITE_ANY, 0,
-			     fnct_MakeCircle, 0, 0);
-    sqlite3_create_function (db, "MakeCircle", 4, SQLITE_ANY, 0,
-			     fnct_MakeCircle, 0, 0);
-    sqlite3_create_function (db, "MakeCircle", 5, SQLITE_ANY, 0,
-			     fnct_MakeCircle, 0, 0);
-    sqlite3_create_function (db, "MakeEllipse", 4, SQLITE_ANY, 0,
-			     fnct_MakeEllipse, 0, 0);
-    sqlite3_create_function (db, "MakeEllipse", 5, SQLITE_ANY, 0,
-			     fnct_MakeEllipse, 0, 0);
-    sqlite3_create_function (db, "MakeEllipse", 6, SQLITE_ANY, 0,
-			     fnct_MakeEllipse, 0, 0);
-    sqlite3_create_function (db, "MakeArc", 5, SQLITE_ANY, 0, fnct_MakeArc, 0,
-			     0);
-    sqlite3_create_function (db, "MakeArc", 6, SQLITE_ANY, 0, fnct_MakeArc, 0,
-			     0);
-    sqlite3_create_function (db, "MakeArc", 7, SQLITE_ANY, 0, fnct_MakeArc, 0,
-			     0);
-    sqlite3_create_function (db, "MakeEllipticArc", 6, SQLITE_ANY, 0,
-			     fnct_MakeEllipticArc, 0, 0);
-    sqlite3_create_function (db, "MakeEllipticArc", 7, SQLITE_ANY, 0,
-			     fnct_MakeEllipticArc, 0, 0);
-    sqlite3_create_function (db, "MakeEllipticArc", 8, SQLITE_ANY, 0,
-			     fnct_MakeEllipticArc, 0, 0);
-    sqlite3_create_function (db, "MakeCircularSector", 5, SQLITE_ANY, 0,
-			     fnct_MakeCircularSector, 0, 0);
-    sqlite3_create_function (db, "MakeCircularSector", 6, SQLITE_ANY, 0,
-			     fnct_MakeCircularSector, 0, 0);
-    sqlite3_create_function (db, "MakeCircularSector", 7, SQLITE_ANY, 0,
-			     fnct_MakeCircularSector, 0, 0);
-    sqlite3_create_function (db, "MakeCircularStripe", 6, SQLITE_ANY, 0,
-			     fnct_MakeCircularStripe, 0, 0);
-    sqlite3_create_function (db, "MakeCircularStripe", 7, SQLITE_ANY, 0,
-			     fnct_MakeCircularStripe, 0, 0);
-    sqlite3_create_function (db, "MakeCircularStripe", 8, SQLITE_ANY, 0,
-			     fnct_MakeCircularStripe, 0, 0);
-    sqlite3_create_function (db, "MakeEllipticSector", 6, SQLITE_ANY, 0,
-			     fnct_MakeEllipticSector, 0, 0);
-    sqlite3_create_function (db, "MakeEllipticSector", 7, SQLITE_ANY, 0,
-			     fnct_MakeEllipticSector, 0, 0);
-    sqlite3_create_function (db, "MakeEllipticSector", 8, SQLITE_ANY, 0,
-			     fnct_MakeEllipticSector, 0, 0);
-    sqlite3_create_function (db, "Collect", 1, SQLITE_ANY, cache, 0,
-			     fnct_Collect_step, fnct_Collect_final);
-    sqlite3_create_function (db, "Collect", 2, SQLITE_ANY, cache, fnct_Collect,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Collect", 1, SQLITE_ANY, cache, 0,
-			     fnct_Collect_step, fnct_Collect_final);
-    sqlite3_create_function (db, "ST_Collect", 2, SQLITE_ANY, cache,
-			     fnct_Collect, 0, 0);
-    sqlite3_create_function (db, "BuildMbrFilter", 4, SQLITE_ANY, 0,
-			     fnct_BuildMbrFilter, 0, 0);
-    sqlite3_create_function (db, "FilterMbrWithin", 4, SQLITE_ANY, 0,
-			     fnct_FilterMbrWithin, 0, 0);
-    sqlite3_create_function (db, "FilterMbrContains", 4, SQLITE_ANY, 0,
-			     fnct_FilterMbrContains, 0, 0);
-    sqlite3_create_function (db, "FilterMbrIntersects", 4, SQLITE_ANY, 0,
-			     fnct_FilterMbrIntersects, 0, 0);
-    sqlite3_create_function (db, "LinesFromRings", 1, SQLITE_ANY, 0,
-			     fnct_LinesFromRings, 0, 0);
-    sqlite3_create_function (db, "ST_LinesFromRings", 1, SQLITE_ANY, 0,
-			     fnct_LinesFromRings, 0, 0);
-    sqlite3_create_function (db, "LinesFromRings", 2, SQLITE_ANY, 0,
-			     fnct_LinesFromRings, 0, 0);
-    sqlite3_create_function (db, "ST_LinesFromRings", 2, SQLITE_ANY, 0,
-			     fnct_LinesFromRings, 0, 0);
-    sqlite3_create_function (db, "ST_NPoints", 1, SQLITE_ANY, 0, fnct_NPoints,
-			     0, 0);
-    sqlite3_create_function (db, "ST_nrings", 1, SQLITE_ANY, 0, fnct_NRings, 0,
-			     0);
-    sqlite3_create_function (db, "ToGARS", 1, SQLITE_ANY, 0, fnct_ToGARS, 0, 0);
-    sqlite3_create_function (db, "GARSMbr", 1, SQLITE_ANY, 0, fnct_GARSMbr, 0,
-			     0);
-    sqlite3_create_function (db, "SnapToGrid", 2, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SnapToGrid", 2, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "SnapToGrid", 3, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SnapToGrid", 3, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "SnapToGrid", 5, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SnapToGrid", 5, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "SnapToGrid", 6, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SnapToGrid", 6, SQLITE_ANY, 0,
-			     fnct_SnapToGrid, 0, 0);
-    sqlite3_create_function (db, "AddPoint", 2, SQLITE_ANY, 0, fnct_AddPoint,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AddPoint", 2, SQLITE_ANY, 0,
-			     fnct_AddPoint, 0, 0);
-    sqlite3_create_function (db, "AddPoint", 3, SQLITE_ANY, 0, fnct_AddPoint,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AddPoint", 3, SQLITE_ANY, 0,
-			     fnct_AddPoint, 0, 0);
-    sqlite3_create_function (db, "RemovePoint", 2, SQLITE_ANY, 0,
-			     fnct_RemovePoint, 0, 0);
-    sqlite3_create_function (db, "ST_RemovePoint", 2, SQLITE_ANY, 0,
-			     fnct_RemovePoint, 0, 0);
-    sqlite3_create_function (db, "SetPoint", 3, SQLITE_ANY, 0, fnct_SetPoint,
-			     0, 0);
-    sqlite3_create_function (db, "ST_SetPoint", 3, SQLITE_ANY, 0,
-			     fnct_SetPoint, 0, 0);
-    sqlite3_create_function (db, "MakePolygon", 1, SQLITE_ANY, 0,
-			     fnct_MakePolygon, 0, 0);
-    sqlite3_create_function (db, "ST_MakePolygon", 1, SQLITE_ANY, 0,
-			     fnct_MakePolygon, 0, 0);
-    sqlite3_create_function (db, "MakePolygon", 2, SQLITE_ANY, 0,
-			     fnct_MakePolygon, 0, 0);
-    sqlite3_create_function (db, "ST_MakePolygon", 2, SQLITE_ANY, 0,
-			     fnct_MakePolygon, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGml", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGml", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGml", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromGml", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_FromGml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGeoJSON", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGeoJSON, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGeoJSON", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGeoJSON, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGeoJSON", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsGeoJSON, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromGeoJSON", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FromGeoJSON, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromKml", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FromKml, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsFGF", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsFGF, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromEWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FromEWKB, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsEWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ToEWKB, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsEWKT", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ToEWKT, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromEWKT", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FromEWKT, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsBinary", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsBinary, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsBinary", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsBinary, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomCollFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomCollFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryCollectionFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryCollectionFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineStringFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineStringFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolygonFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolygonFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MLineFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MLineFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiLineStringFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiLineStringFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPolygonFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPolygonFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomCollFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomCollFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryCollectionFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryCollectionFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineStringFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineStringFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolygonFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PolygonFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MLineFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MLineFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiLineStringFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiLineStringFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPolygonFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MultiPolygonFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_WKTToSQL", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_WktToSql, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomCollFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomCollFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryCollectionFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryCollectionFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineStringFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineStringFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolygonFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolygonFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPointFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPointFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MLineFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MLineFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiLineStringFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiLineStringFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPolygonFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPolygonFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_WKBToSQL", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_WkbToSql, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomCollFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeomCollFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryCollectionFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryCollectionFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomCollFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineStringFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineStringFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolygonFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PolygonFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPointFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPointFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPointFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MLineFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MLineFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiLineStringFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiLineStringFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MLineFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPolygonFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MultiPolygonFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MPolyFromWkb2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromFGF", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryFromFGF1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromFGF", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryFromFGF2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CompressGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CompressGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UncompressGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_UncompressGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SanitizeGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SanitizeGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToInteger", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToInteger, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToDouble", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToDouble, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToText, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToText, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToBlob", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ForceAsNull", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ForceAsNull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateUUID", 0, SQLITE_UTF8, 0,
+				fnct_CreateUUID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MD5Checksum", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MD5Checksum, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MD5TotalChecksum", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_MD5TotalChecksum_step,
+				fnct_MD5TotalChecksum_final, 0);
+    sqlite3_create_function_v2 (db, "CastToPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToLinestring", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToLinestring, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToPolygon", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToPolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToMultiPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToMultiPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToMultiLinestring", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToMultiLinestring, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToMultiPolygon", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToMultiPolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToGeometryCollection", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToGeometryCollection, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToMulti", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToMulti, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Multi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToMulti, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToSingle", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToSingle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToXY", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToXY, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToXYZ", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToXYZ, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToXYM", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToXYM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastToXYZM", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastToXYZM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ExtractMultiPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ExtractMultiPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ExtractMultiLinestring", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ExtractMultiLinestring, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ExtractMultiPolygon", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ExtractMultiPolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Reverse", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Reverse, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ForceLHR", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ForceLHR, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Dimension", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Dimension, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Dimension", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Dimension, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CoordDimension", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CoordDimension, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_NDims", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NDims, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryType", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryType, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryType", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryType, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryAliasType", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryAliasType, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SridFromAuthCRS", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SridFromAuthCRS, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SRID", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SRID", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SetSRID", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsEmpty", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsEmpty, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsEmpty", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsEmpty, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Is3D", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Is3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsMeasured", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsMeasured, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Envelope", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Envelope, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Envelope", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Envelope, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Expand", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Expand, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "X", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_X, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Y", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_Y, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Z", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_Z, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "M", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_M, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_X", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, fnct_X,
+				0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Y", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, fnct_Y,
+				0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Z", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, fnct_Z,
+				0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_M", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, fnct_M,
+				0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MinX", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMinX, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MinY", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMinY, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MinZ", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MinZ, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MinM", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MinM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MaxX", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMaxX, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MaxY", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMaxY, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MaxZ", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MaxZ, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MaxM", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MaxM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "NumPoints", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumPoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_NumPoints", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumPoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "StartPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_StartPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "EndPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_EndPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_StartPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_StartPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_EndPoint", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_EndPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_PointN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ExteriorRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ExteriorRing, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ExteriorRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ExteriorRing, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "NumInteriorRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumInteriorRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "NumInteriorRings", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumInteriorRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_NumInteriorRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumInteriorRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "InteriorRingN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InteriorRingN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_InteriorRingN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_InteriorRingN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "NumGeometries", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumGeometries, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_NumGeometries", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NumGeometries, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeometryN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeometryN", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeometryN, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MBRContains", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrContains, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrDisjoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrDisjoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MBREqual", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrEqual, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrIntersects", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_EnvIntersects", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_EnvIntersects", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_EnvIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_EnvelopesIntersects", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_EnvelopesIntersects", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_EnvIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MBROverlaps", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrOverlaps, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrTouches", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrTouches, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrWithin", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrWithin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ShiftCoords", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ShiftCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ShiftCoordinates", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ShiftCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Translate", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Translate, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Shift_Longitude", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ShiftLongitude, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "NormalizeLonLat", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NormalizeLonLat, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ScaleCoords", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ScaleCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ScaleCoordinates", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ScaleCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ScaleCoords", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ScaleCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ScaleCoordinates", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ScaleCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RotateCoords", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RotateCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RotateCoordinates", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RotateCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ReflectCoords", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ReflectCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ReflectCoordinates", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ReflectCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SwapCoords", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SwapCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SwapCoordinates", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SwapCoords, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BuildMbr", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_BuildMbr1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BuildMbr", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_BuildMbr2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BuildCircleMbr", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_BuildCircleMbr1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BuildCircleMbr", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_BuildCircleMbr2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Extent", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_Extent_step, fnct_Extent_final, 0);
+    sqlite3_create_function_v2 (db, "MbrMinX", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMinX, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrMaxX", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMaxX, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrMinY", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMinY, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MbrMaxY", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MbrMaxY, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Point", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePoint1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePoint1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePoint2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointZ", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointZ1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointZ", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointZ2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointM", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointM1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointM", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointM2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointZM", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointZM1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePointZM", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePointZM2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeLine", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_MakeLine_step, fnct_MakeLine_final, 0);
+    sqlite3_create_function_v2 (db, "MakeLine", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeLine, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircle", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircle", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircle", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipse", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipse, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipse", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipse, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipse", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipse, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeArc", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeArc", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeArc", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticArc", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticArc", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticArc", 8,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticArc, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularSector", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularSector", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularSector", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularStripe", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularStripe, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularStripe", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularStripe, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeCircularStripe", 8,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeCircularStripe, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticSector", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticSector", 7,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeEllipticSector", 8,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeEllipticSector, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Collect", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Collect_step, fnct_Collect_final, 0);
+    sqlite3_create_function_v2 (db, "Collect", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Collect, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Collect", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Collect_step, fnct_Collect_final, 0);
+    sqlite3_create_function_v2 (db, "ST_Collect", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Collect, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BuildMbrFilter", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_BuildMbrFilter, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "FilterMbrWithin", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FilterMbrWithin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "FilterMbrContains", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FilterMbrContains, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "FilterMbrIntersects", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_FilterMbrIntersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LinesFromRings", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesFromRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LinesFromRings", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesFromRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LinesFromRings", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesFromRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LinesFromRings", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesFromRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_NPoints", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NPoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_nrings", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_NRings, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ToGARS", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ToGARS, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GARSMbr", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GARSMbr, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SnapToGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SnapToGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SnapToGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SnapToGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SnapToGrid", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SnapToGrid", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SnapToGrid", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SnapToGrid", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SnapToGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AddPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AddPoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AddPoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AddPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RemovePoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RemovePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_RemovePoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RemovePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SetPoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SetPoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SetStartPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetStartPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SetStartPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetStartPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SetEndPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetEndPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SetEndPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetEndPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePolygon", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MakePolygon", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakePolygon", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePolygon, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MakePolygon", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakePolygon, 0, 0, 0);
 
 #ifndef OMIT_GEOS		/* including GEOS */
-    sqlite3_create_function (db, "BuildArea", 1, SQLITE_ANY, cache,
-			     fnct_BuildArea, 0, 0);
-    sqlite3_create_function (db, "ST_BuildArea", 1, SQLITE_ANY, cache,
-			     fnct_BuildArea, 0, 0);
-    sqlite3_create_function (db, "Polygonize", 1, SQLITE_ANY, cache, 0,
-			     fnct_Polygonize_step, fnct_Polygonize_final);
-    sqlite3_create_function (db, "ST_Polygonize", 1, SQLITE_ANY, cache, 0,
-			     fnct_Polygonize_step, fnct_Polygonize_final);
+    sqlite3_create_function_v2 (db, "BuildArea", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BuildArea, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BuildArea", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BuildArea, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Polygonize", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Polygonize_step, fnct_Polygonize_final, 0);
+    sqlite3_create_function_v2 (db, "ST_Polygonize", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Polygonize_step, fnct_Polygonize_final, 0);
 #endif /* end including GEOS */
 
-    sqlite3_create_function (db, "DissolveSegments", 1, SQLITE_ANY, 0,
-			     fnct_DissolveSegments, 0, 0);
-    sqlite3_create_function (db, "ST_DissolveSegments", 1, SQLITE_ANY, 0,
-			     fnct_DissolveSegments, 0, 0);
-    sqlite3_create_function (db, "DissolvePoints", 1, SQLITE_ANY, 0,
-			     fnct_DissolvePoints, 0, 0);
-    sqlite3_create_function (db, "ST_DissolvePoints", 1, SQLITE_ANY, 0,
-			     fnct_DissolvePoints, 0, 0);
-    sqlite3_create_function (db, "CollectionExtract", 2, SQLITE_ANY, 0,
-			     fnct_CollectionExtract, 0, 0);
-    sqlite3_create_function (db, "ST_CollectionExtract", 2, SQLITE_ANY, 0,
-			     fnct_CollectionExtract, 0, 0);
-    sqlite3_create_function (db, "ST_Locate_Along_Measure", 2, SQLITE_ANY, 0,
-			     fnct_LocateBetweenMeasures, 0, 0);
-    sqlite3_create_function (db, "ST_LocateAlong", 2, SQLITE_ANY, 0,
-			     fnct_LocateBetweenMeasures, 0, 0);
-    sqlite3_create_function (db, "ST_Locate_Between_Measures", 3, SQLITE_ANY,
-			     0, fnct_LocateBetweenMeasures, 0, 0);
-    sqlite3_create_function (db, "ST_LocateBetween", 3, SQLITE_ANY, 0,
-			     fnct_LocateBetweenMeasures, 0, 0);
+    sqlite3_create_function_v2 (db, "DissolveSegments", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DissolveSegments, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_DissolveSegments", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DissolveSegments, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DissolvePoints", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DissolvePoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_DissolvePoints", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DissolvePoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CollectionExtract", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CollectionExtract, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_CollectionExtract", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CollectionExtract, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Locate_Along_Measure", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LocateBetweenMeasures, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LocateAlong", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LocateBetweenMeasures, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Locate_Between_Measures", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LocateBetweenMeasures, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LocateBetween", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LocateBetweenMeasures, 0, 0, 0);
 #ifndef OMIT_GEOCALLBACKS	/* supporting RTree geometry callbacks */
     sqlite3_rtree_geometry_callback (db, "RTreeWithin", fnct_RTreeIntersects,
 				     0);
@@ -29098,35 +31297,67 @@ register_spatialite_sql_functions (void *p_db, const void *p_cache)
 #endif /* end RTree geometry callbacks */
 
 /* some BLOB/JPEG/EXIF functions */
-    sqlite3_create_function (db, "IsGeometryBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsGeometryBlob, 0, 0);
-    sqlite3_create_function (db, "IsZipBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsZipBlob, 0, 0);
-    sqlite3_create_function (db, "IsPdfBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsPdfBlob, 0, 0);
-    sqlite3_create_function (db, "IsTiffBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsTiffBlob, 0, 0);
-    sqlite3_create_function (db, "IsGifBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsGifBlob, 0, 0);
-    sqlite3_create_function (db, "IsPngBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsPngBlob, 0, 0);
-    sqlite3_create_function (db, "IsJpegBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsJpegBlob, 0, 0);
-    sqlite3_create_function (db, "IsExifBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsExifBlob, 0, 0);
-    sqlite3_create_function (db, "IsExifGpsBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsExifGpsBlob, 0, 0);
-    sqlite3_create_function (db, "IsWebpBlob", 1, SQLITE_ANY, 0,
-			     fnct_IsWebPBlob, 0, 0);
-    sqlite3_create_function (db, "GeomFromExifGpsBlob", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromExifGpsBlob, 0, 0);
-    sqlite3_create_function (db, "GetMimeType", 1, SQLITE_ANY, 0,
-			     fnct_GetMimeType, 0, 0);
-    sqlite3_create_function (db, "CountUnsafeTriggers", 0, SQLITE_ANY, 0,
-			     fnct_CountUnsafeTriggers, 0, 0);
+    sqlite3_create_function_v2 (db, "IsGeometryBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsGeometryBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsZipBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsZipBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsPdfBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsPdfBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsTiffBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsTiffBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsGifBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsGifBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsPngBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsPngBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsJpegBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsJpegBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsExifBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsExifBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsExifGpsBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsExifGpsBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsWebpBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsWebPBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsJP2Blob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsJP2Blob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromExifGpsBlob", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromExifGpsBlob, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GetMimeType", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GetMimeType, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CountUnsafeTriggers", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CountUnsafeTriggers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CheckDuplicateRows", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CheckDuplicateRows, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RemoveDuplicateRows", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RemoveDuplicateRows, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ElementaryGeometries", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ElementaryGeometries, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DropGeoTable", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DropGeoTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DropGeoTable", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_DropGeoTable, 0, 0, 0);
 
 /*
-// enabling BlobFromFile, BlobToFile and XB_LoadXML, XB_StoreXML, ExportDXF
+// enabling BlobFromFile, BlobToFile and XB_LoadXML, XB_StoreXML, 
+// ExportDXF and other import/export functions
 //
 // these functions could potentially introduce serious security issues,
 // most notably when invoked from within some Trigger
@@ -29151,603 +31382,1005 @@ register_spatialite_sql_functions (void *p_db, const void *p_cache)
 	;
     else if (strcasecmp (security_level, "relaxed") == 0)
       {
-	  sqlite3_create_function (db, "BlobFromFile", 1, SQLITE_ANY, 0,
-				   fnct_BlobFromFile, 0, 0);
-	  sqlite3_create_function (db, "BlobToFile", 2, SQLITE_ANY, 0,
-				   fnct_BlobToFile, 0, 0);
-	  sqlite3_create_function (db, "ExportDXF", 9, SQLITE_ANY, 0,
-				   fnct_ExportDXF, 0, 0);
-	  sqlite3_create_function (db, "ExportDXF", 10, SQLITE_ANY, 0,
-				   fnct_ExportDXF, 0, 0);
+	  sqlite3_create_function_v2 (db, "BlobFromFile", 1,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_BlobFromFile, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "BlobToFile", 2,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_BlobToFile, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDXF", 1,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				      fnct_ImportDXF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDXF", 8,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				      fnct_ImportDXF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDXFfromDir", 1,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				      fnct_ImportDXFfromDir, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDXFfromDir", 8,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				      fnct_ImportDXFfromDir, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportDXF", 9,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportDXF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportDXF", 10,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportDXF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDBF", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportDBF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDBF", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportDBF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportDBF", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportDBF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportDBF", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportDBF, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 6,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 7,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 8,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 9,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 10,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportSHP", 11,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportSHP", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportSHP", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportSHP, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportKML", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportKML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportKML", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportKML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportKML", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportKML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportKML", 6,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportKML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportGeoJSON", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportGeoJSON, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportGeoJSON", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportGeoJSON, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ExportGeoJSON", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ExportGeoJSON, 0, 0, 0);
 
 #ifdef ENABLE_LIBXML2		/* including LIBXML2 */
 
-	  sqlite3_create_function (db, "XB_LoadXML", 1, SQLITE_ANY, cache,
-				   fnct_XB_LoadXML, 0, 0);
-	  sqlite3_create_function (db, "XB_StoreXML", 2, SQLITE_ANY, 0,
-				   fnct_XB_StoreXML, 0, 0);
-	  sqlite3_create_function (db, "XB_StoreXML", 3, SQLITE_ANY, 0,
-				   fnct_XB_StoreXML, 0, 0);
+	  sqlite3_create_function_v2 (db, "XB_LoadXML", 1,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				      fnct_XB_LoadXML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "XB_StoreXML", 2,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_XB_StoreXML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "XB_StoreXML", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_XB_StoreXML, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportWFS", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportWFS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportWFS", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportWFS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportWFS", 5,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportWFS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportWFS", 6,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportWFS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportWFS", 7,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportWFS, 0, 0, 0);
 
 #endif /* end including LIBXML2 */
 
+#ifndef OMIT_FREEXL		/* FREEXL is enabled */
+	  sqlite3_create_function_v2 (db, "ImportXLS", 2,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportXLS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportXLS", 3,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportXLS, 0, 0, 0);
+	  sqlite3_create_function_v2 (db, "ImportXLS", 4,
+				      SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				      fnct_ImportXLS, 0, 0, 0);
+#endif /* end FREEXL support */
+
       }
 
 /* some Geodesic functions */
-    sqlite3_create_function (db, "GreatCircleLength", 1, SQLITE_ANY, 0,
-			     fnct_GreatCircleLength, 0, 0);
-    sqlite3_create_function (db, "GeodesicLength", 1, SQLITE_ANY, 0,
-			     fnct_GeodesicLength, 0, 0);
+    sqlite3_create_function_v2 (db, "GreatCircleLength", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GreatCircleLength, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeodesicLength", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeodesicLength, 0, 0, 0);
 
 /* some Length Unit conversion functions */
-    sqlite3_create_function (db, "CvtToKm", 1, SQLITE_ANY, 0, fnct_cvtToKm, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToDm", 1, SQLITE_ANY, 0, fnct_cvtToDm, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToCm", 1, SQLITE_ANY, 0, fnct_cvtToCm, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToMm", 1, SQLITE_ANY, 0, fnct_cvtToMm, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToKmi", 1, SQLITE_ANY, 0, fnct_cvtToKmi,
-			     0, 0);
-    sqlite3_create_function (db, "CvtToIn", 1, SQLITE_ANY, 0, fnct_cvtToIn, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToFt", 1, SQLITE_ANY, 0, fnct_cvtToFt, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToYd", 1, SQLITE_ANY, 0, fnct_cvtToYd, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToMi", 1, SQLITE_ANY, 0, fnct_cvtToMi, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToFath", 1, SQLITE_ANY, 0,
-			     fnct_cvtToFath, 0, 0);
-    sqlite3_create_function (db, "CvtToCh", 1, SQLITE_ANY, 0, fnct_cvtToCh, 0,
-			     0);
-    sqlite3_create_function (db, "CvtToLink", 1, SQLITE_ANY, 0,
-			     fnct_cvtToLink, 0, 0);
-    sqlite3_create_function (db, "CvtToUsIn", 1, SQLITE_ANY, 0,
-			     fnct_cvtToUsIn, 0, 0);
-    sqlite3_create_function (db, "CvtToUsFt", 1, SQLITE_ANY, 0,
-			     fnct_cvtToUsFt, 0, 0);
-    sqlite3_create_function (db, "CvtToUsYd", 1, SQLITE_ANY, 0,
-			     fnct_cvtToUsYd, 0, 0);
-    sqlite3_create_function (db, "CvtToUsCh", 1, SQLITE_ANY, 0,
-			     fnct_cvtToUsCh, 0, 0);
-    sqlite3_create_function (db, "CvtToUsMi", 1, SQLITE_ANY, 0,
-			     fnct_cvtToUsMi, 0, 0);
-    sqlite3_create_function (db, "CvtToIndFt", 1, SQLITE_ANY, 0,
-			     fnct_cvtToIndFt, 0, 0);
-    sqlite3_create_function (db, "CvtToIndYd", 1, SQLITE_ANY, 0,
-			     fnct_cvtToIndYd, 0, 0);
-    sqlite3_create_function (db, "CvtToIndCh", 1, SQLITE_ANY, 0,
-			     fnct_cvtToIndCh, 0, 0);
-    sqlite3_create_function (db, "CvtFromKm", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromKm, 0, 0);
-    sqlite3_create_function (db, "CvtFromDm", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromDm, 0, 0);
-    sqlite3_create_function (db, "CvtFromCm", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromCm, 0, 0);
-    sqlite3_create_function (db, "CvtFromMm", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromMm, 0, 0);
-    sqlite3_create_function (db, "CvtFromKmi", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromKmi, 0, 0);
-    sqlite3_create_function (db, "CvtFromIn", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromIn, 0, 0);
-    sqlite3_create_function (db, "CvtFromFt", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromFt, 0, 0);
-    sqlite3_create_function (db, "CvtFromYd", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromYd, 0, 0);
-    sqlite3_create_function (db, "CvtFromMi", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromMi, 0, 0);
-    sqlite3_create_function (db, "CvtFromFath", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromFath, 0, 0);
-    sqlite3_create_function (db, "CvtFromCh", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromCh, 0, 0);
-    sqlite3_create_function (db, "CvtFromLink", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromLink, 0, 0);
-    sqlite3_create_function (db, "CvtFromUsIn", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromUsIn, 0, 0);
-    sqlite3_create_function (db, "CvtFromUsFt", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromUsFt, 0, 0);
-    sqlite3_create_function (db, "CvtFromUsYd", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromUsYd, 0, 0);
-    sqlite3_create_function (db, "CvtFromUsCh", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromUsCh, 0, 0);
-    sqlite3_create_function (db, "CvtFromUsMi", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromUsMi, 0, 0);
-    sqlite3_create_function (db, "CvtFromIndFt", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromIndFt, 0, 0);
-    sqlite3_create_function (db, "CvtFromIndYd", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromIndYd, 0, 0);
-    sqlite3_create_function (db, "CvtFromIndCh", 1, SQLITE_ANY, 0,
-			     fnct_cvtFromIndCh, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToKm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToKm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToDm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToDm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToCm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToCm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToMm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToMm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToKmi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToKmi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToIn", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToIn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToMi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToMi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToFath", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToFath, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToCh, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToLink", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToLink, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToUsIn", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToUsIn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToUsFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToUsFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToUsYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToUsYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToUsCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToUsCh, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToUsMi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToUsMi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToIndFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToIndFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToIndYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToIndYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtToIndCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtToIndCh, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromKm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromKm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromDm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromDm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromCm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromCm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromMm", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromMm, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromKmi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromKmi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromIn", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromIn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromMi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromMi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromFath", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromFath, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromCh, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromLink", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromLink, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromUsIn", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromUsIn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromUsFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromUsFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromUsYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromUsYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromUsCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromUsCh, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromUsMi", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromUsMi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromIndFt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromIndFt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromIndYd", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromIndYd, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CvtFromIndCh", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_cvtFromIndCh, 0, 0, 0);
 
 /* DMS (Degrees/Minutes/Seconds) to DD (decimal degrees) */
-    sqlite3_create_function (db, "LongitudeFromDMS", 1, SQLITE_ANY, 0,
-			     fnct_longFromDMS, 0, 0);
-    sqlite3_create_function (db, "LatitudeFromDMS", 1, SQLITE_ANY, 0,
-			     fnct_latFromDMS, 0, 0);
-    sqlite3_create_function (db, "LongLatToDMS", 2, SQLITE_ANY, 0, fnct_toDMS,
-			     0, 0);
+    sqlite3_create_function_v2 (db, "LongitudeFromDMS", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_longFromDMS, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LatitudeFromDMS", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_latFromDMS, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LongLatToDMS", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_toDMS, 0, 0, 0);
 
 #ifndef OMIT_MATHSQL		/* supporting SQL math functions */
 
 /* some extra math functions */
-    sqlite3_create_function (db, "acos", 1, SQLITE_ANY, 0, fnct_math_acos, 0,
-			     0);
-    sqlite3_create_function (db, "asin", 1, SQLITE_ANY, 0, fnct_math_asin, 0,
-			     0);
-    sqlite3_create_function (db, "atan", 1, SQLITE_ANY, 0, fnct_math_atan, 0,
-			     0);
-    sqlite3_create_function (db, "ceil", 1, SQLITE_ANY, 0, fnct_math_ceil, 0,
-			     0);
-    sqlite3_create_function (db, "ceiling", 1, SQLITE_ANY, 0, fnct_math_ceil,
-			     0, 0);
-    sqlite3_create_function (db, "cos", 1, SQLITE_ANY, 0, fnct_math_cos, 0, 0);
-    sqlite3_create_function (db, "cot", 1, SQLITE_ANY, 0, fnct_math_cot, 0, 0);
-    sqlite3_create_function (db, "degrees", 1, SQLITE_ANY, 0,
-			     fnct_math_degrees, 0, 0);
-    sqlite3_create_function (db, "exp", 1, SQLITE_ANY, 0, fnct_math_exp, 0, 0);
-    sqlite3_create_function (db, "floor", 1, SQLITE_ANY, 0, fnct_math_floor,
-			     0, 0);
-    sqlite3_create_function (db, "ln", 1, SQLITE_ANY, 0, fnct_math_logn, 0, 0);
-    sqlite3_create_function (db, "log", 1, SQLITE_ANY, 0, fnct_math_logn, 0, 0);
-    sqlite3_create_function (db, "log", 2, SQLITE_ANY, 0, fnct_math_logn2, 0,
-			     0);
-    sqlite3_create_function (db, "log2", 1, SQLITE_ANY, 0, fnct_math_log_2, 0,
-			     0);
-    sqlite3_create_function (db, "log10", 1, SQLITE_ANY, 0, fnct_math_log_10,
-			     0, 0);
-    sqlite3_create_function (db, "pi", 0, SQLITE_ANY, 0, fnct_math_pi, 0, 0);
-    sqlite3_create_function (db, "pow", 2, SQLITE_ANY, 0, fnct_math_pow, 0, 0);
-    sqlite3_create_function (db, "power", 2, SQLITE_ANY, 0, fnct_math_pow, 0,
-			     0);
-    sqlite3_create_function (db, "radians", 1, SQLITE_ANY, 0,
-			     fnct_math_radians, 0, 0);
-    sqlite3_create_function (db, "sign", 1, SQLITE_ANY, 0, fnct_math_sign, 0,
-			     0);
-    sqlite3_create_function (db, "sin", 1, SQLITE_ANY, 0, fnct_math_sin, 0, 0);
-    sqlite3_create_function (db, "stddev_pop", 1, SQLITE_ANY, 0, 0,
-			     fnct_math_stddev_step, fnct_math_stddev_pop_final);
-    sqlite3_create_function (db, "stddev_samp", 1, SQLITE_ANY, 0, 0,
-			     fnct_math_stddev_step,
-			     fnct_math_stddev_samp_final);
-    sqlite3_create_function (db, "sqrt", 1, SQLITE_ANY, 0, fnct_math_sqrt, 0,
-			     0);
-    sqlite3_create_function (db, "tan", 1, SQLITE_ANY, 0, fnct_math_tan, 0, 0);
-    sqlite3_create_function (db, "var_pop", 1, SQLITE_ANY, 0, 0,
-			     fnct_math_stddev_step, fnct_math_var_pop_final);
-    sqlite3_create_function (db, "var_samp", 1, SQLITE_ANY, 0, 0,
-			     fnct_math_stddev_step, fnct_math_var_samp_final);
+    sqlite3_create_function_v2 (db, "acos", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_acos, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "asin", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_asin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "atan", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_atan, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ceil", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_ceil, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ceiling", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_ceil, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "cos", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_cos, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "cot", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_cot, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "degrees", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_degrees, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "exp", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_exp, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "floor", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_floor, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ln", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_math_logn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "log", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_logn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "log", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_logn2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "log2", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_log_2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "log10", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_log_10, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "pi", 0, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+				0, fnct_math_pi, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "pow", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_pow, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "power", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_pow, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "radians", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_radians, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "sign", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_sign, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "sin", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_sin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "stddev_pop", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_math_stddev_step,
+				fnct_math_stddev_pop_final, 0);
+    sqlite3_create_function_v2 (db, "stddev_samp", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_math_stddev_step,
+				fnct_math_stddev_samp_final, 0);
+    sqlite3_create_function_v2 (db, "sqrt", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_sqrt, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "tan", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_math_tan, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "var_pop", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_math_stddev_step, fnct_math_var_pop_final,
+				0);
+    sqlite3_create_function_v2 (db, "var_samp", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, 0,
+				fnct_math_stddev_step, fnct_math_var_samp_final,
+				0);
 
 #endif /* end supporting SQL math functions */
 
 #ifndef OMIT_PROJ		/* including PROJ.4 */
 
-    sqlite3_create_function (db, "Transform", 2, SQLITE_ANY, cache,
-			     fnct_Transform, 0, 0);
-    sqlite3_create_function (db, "ST_Transform", 2, SQLITE_ANY, cache,
-			     fnct_Transform, 0, 0);
+    sqlite3_create_function_v2 (db, "Transform", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Transform, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Transform", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Transform, 0, 0, 0);
 
 #endif /* end including PROJ.4 */
 
 #ifndef OMIT_GEOS		/* including GEOS */
 
-    sqlite3_create_function (db, "GEOS_GetLastErrorMsg", 0, SQLITE_ANY,
-			     cache, fnct_GEOS_GetLastErrorMsg, 0, 0);
-    sqlite3_create_function (db, "GEOS_GetLastWarningMsg", 0, SQLITE_ANY,
-			     cache, fnct_GEOS_GetLastWarningMsg, 0, 0);
-    sqlite3_create_function (db, "GEOS_GetLastAuxErrorMsg", 0, SQLITE_ANY,
-			     cache, fnct_GEOS_GetLastAuxErrorMsg, 0, 0);
-    sqlite3_create_function (db, "GEOS_GetCriticalPointFromMsg", 0, SQLITE_ANY,
-			     cache, fnct_GEOS_GetCriticalPointFromMsg, 0, 0);
-    sqlite3_create_function (db, "GEOS_GetCriticalPointFromMsg", 1, SQLITE_ANY,
-			     cache, fnct_GEOS_GetCriticalPointFromMsg, 0, 0);
-    sqlite3_create_function (db, "IsValidReason", 1, SQLITE_ANY,
-			     cache, fnct_IsValidReason, 0, 0);
-    sqlite3_create_function (db, "ST_IsValidReason", 1, SQLITE_ANY,
-			     cache, fnct_IsValidReason, 0, 0);
-    sqlite3_create_function (db, "IsValidDetail", 1, SQLITE_ANY,
-			     cache, fnct_IsValidDetail, 0, 0);
-    sqlite3_create_function (db, "ST_IsValidDetail", 1, SQLITE_ANY,
-			     cache, fnct_IsValidDetail, 0, 0);
-
-    sqlite3_create_function (db, "Boundary", 1, SQLITE_ANY, cache,
-			     fnct_Boundary, 0, 0);
-    sqlite3_create_function (db, "ST_Boundary", 1, SQLITE_ANY, cache,
-			     fnct_Boundary, 0, 0);
-    sqlite3_create_function (db, "IsClosed", 1, SQLITE_ANY, 0, fnct_IsClosed, 0,
-			     0);
-    sqlite3_create_function (db, "ST_IsClosed", 1, SQLITE_ANY, 0, fnct_IsClosed,
-			     0, 0);
-    sqlite3_create_function (db, "IsSimple", 1, SQLITE_ANY, cache,
-			     fnct_IsSimple, 0, 0);
-    sqlite3_create_function (db, "ST_IsSimple", 1, SQLITE_ANY, cache,
-			     fnct_IsSimple, 0, 0);
-    sqlite3_create_function (db, "IsRing", 1, SQLITE_ANY, cache, fnct_IsRing, 0,
-			     0);
-    sqlite3_create_function (db, "ST_IsRing", 1, SQLITE_ANY, cache, fnct_IsRing,
-			     0, 0);
-    sqlite3_create_function (db, "IsValid", 1, SQLITE_ANY, cache, fnct_IsValid,
-			     0, 0);
-    sqlite3_create_function (db, "ST_IsValid", 1, SQLITE_ANY, cache,
-			     fnct_IsValid, 0, 0);
-    sqlite3_create_function (db, "GLength", 1, SQLITE_ANY, cache, fnct_Length,
-			     0, 0);
-    sqlite3_create_function (db, "GLength", 2, SQLITE_ANY, cache, fnct_Length,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Length", 1, SQLITE_ANY, cache, fnct_Length,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Length", 2, SQLITE_ANY, cache, fnct_Length,
-			     0, 0);
-    sqlite3_create_function (db, "Perimeter", 1, SQLITE_ANY, cache,
-			     fnct_Perimeter, 0, 0);
-    sqlite3_create_function (db, "Perimeter", 2, SQLITE_ANY, cache,
-			     fnct_Perimeter, 0, 0);
-    sqlite3_create_function (db, "ST_Perimeter", 1, SQLITE_ANY, cache,
-			     fnct_Perimeter, 0, 0);
-    sqlite3_create_function (db, "ST_Perimeter", 2, SQLITE_ANY, cache,
-			     fnct_Perimeter, 0, 0);
-    sqlite3_create_function (db, "Area", 1, SQLITE_ANY, cache, fnct_Area, 0, 0);
-    sqlite3_create_function (db, "ST_Area", 1, SQLITE_ANY, cache, fnct_Area, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Centroid", 1, SQLITE_ANY, cache,
-			     fnct_Centroid, 0, 0);
-    sqlite3_create_function (db, "Centroid", 1, SQLITE_ANY, cache,
-			     fnct_Centroid, 0, 0);
-    sqlite3_create_function (db, "PointOnSurface", 1, SQLITE_ANY, cache,
-			     fnct_PointOnSurface, 0, 0);
-    sqlite3_create_function (db, "ST_PointOnSurface", 1, SQLITE_ANY, cache,
-			     fnct_PointOnSurface, 0, 0);
-    sqlite3_create_function (db, "Simplify", 2, SQLITE_ANY, cache,
-			     fnct_Simplify, 0, 0);
-    sqlite3_create_function (db, "ST_Simplify", 2, SQLITE_ANY, cache,
-			     fnct_Simplify, 0, 0);
-    sqlite3_create_function (db, "ST_Generalize", 2, SQLITE_ANY, cache,
-			     fnct_Simplify, 0, 0);
-    sqlite3_create_function (db, "SimplifyPreserveTopology", 2, SQLITE_ANY,
-			     cache, fnct_SimplifyPreserveTopology, 0, 0);
-    sqlite3_create_function (db, "ST_SimplifyPreserveTopology", 2, SQLITE_ANY,
-			     cache, fnct_SimplifyPreserveTopology, 0, 0);
-    sqlite3_create_function (db, "ConvexHull", 1, SQLITE_ANY, cache,
-			     fnct_ConvexHull, 0, 0);
-    sqlite3_create_function (db, "ST_ConvexHull", 1, SQLITE_ANY, cache,
-			     fnct_ConvexHull, 0, 0);
-    sqlite3_create_function (db, "Buffer", 2, SQLITE_ANY, cache, fnct_Buffer, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Buffer", 2, SQLITE_ANY, cache, fnct_Buffer,
-			     0, 0);
-    sqlite3_create_function (db, "Intersection", 2, SQLITE_ANY, cache,
-			     fnct_Intersection, 0, 0);
-    sqlite3_create_function (db, "ST_Intersection", 2, SQLITE_ANY, cache,
-			     fnct_Intersection, 0, 0);
-    sqlite3_create_function (db, "GUnion", 1, SQLITE_ANY, cache, 0,
-			     fnct_Union_step, fnct_Union_final);
-    sqlite3_create_function (db, "GUnion", 2, SQLITE_ANY, cache, fnct_Union, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Union", 1, SQLITE_ANY, cache, 0,
-			     fnct_Union_step, fnct_Union_final);
-    sqlite3_create_function (db, "ST_Union", 2, SQLITE_ANY, cache, fnct_Union,
-			     0, 0);
-    sqlite3_create_function (db, "Difference", 2, SQLITE_ANY, cache,
-			     fnct_Difference, 0, 0);
-    sqlite3_create_function (db, "ST_Difference", 2, SQLITE_ANY, cache,
-			     fnct_Difference, 0, 0);
-    sqlite3_create_function (db, "SymDifference", 2, SQLITE_ANY, cache,
-			     fnct_SymDifference, 0, 0);
-    sqlite3_create_function (db, "ST_SymDifference", 2, SQLITE_ANY, cache,
-			     fnct_SymDifference, 0, 0);
-    sqlite3_create_function (db, "Equals", 2, SQLITE_ANY, cache, fnct_Equals, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Equals", 2, SQLITE_ANY, cache, fnct_Equals,
-			     0, 0);
-    sqlite3_create_function (db, "Intersects", 2, SQLITE_ANY, cache,
-			     fnct_Intersects, 0, 0);
-    sqlite3_create_function (db, "ST_Intersects", 2, SQLITE_ANY, cache,
-			     fnct_Intersects, 0, 0);
-    sqlite3_create_function (db, "Disjoint", 2, SQLITE_ANY, cache,
-			     fnct_Disjoint, 0, 0);
-    sqlite3_create_function (db, "ST_Disjoint", 2, SQLITE_ANY, cache,
-			     fnct_Disjoint, 0, 0);
-    sqlite3_create_function (db, "Overlaps", 2, SQLITE_ANY, cache,
-			     fnct_Overlaps, 0, 0);
-    sqlite3_create_function (db, "ST_Overlaps", 2, SQLITE_ANY, cache,
-			     fnct_Overlaps, 0, 0);
-    sqlite3_create_function (db, "Crosses", 2, SQLITE_ANY, cache, fnct_Crosses,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Crosses", 2, SQLITE_ANY, cache,
-			     fnct_Crosses, 0, 0);
-    sqlite3_create_function (db, "Touches", 2, SQLITE_ANY, cache, fnct_Touches,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Touches", 2, SQLITE_ANY, cache,
-			     fnct_Touches, 0, 0);
-    sqlite3_create_function (db, "Within", 2, SQLITE_ANY, cache, fnct_Within, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Within", 2, SQLITE_ANY, cache, fnct_Within,
-			     0, 0);
-    sqlite3_create_function (db, "Contains", 2, SQLITE_ANY, cache,
-			     fnct_Contains, 0, 0);
-    sqlite3_create_function (db, "ST_Contains", 2, SQLITE_ANY, cache,
-			     fnct_Contains, 0, 0);
-    sqlite3_create_function (db, "Relate", 3, SQLITE_ANY, cache, fnct_Relate, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Relate", 3, SQLITE_ANY, cache, fnct_Relate,
-			     0, 0);
-    sqlite3_create_function (db, "Distance", 2, SQLITE_ANY, cache,
-			     fnct_Distance, 0, 0);
-    sqlite3_create_function (db, "Distance", 3, SQLITE_ANY, cache,
-			     fnct_Distance, 0, 0);
-    sqlite3_create_function (db, "ST_Distance", 2, SQLITE_ANY, cache,
-			     fnct_Distance, 0, 0);
-    sqlite3_create_function (db, "ST_Distance", 3, SQLITE_ANY, cache,
-			     fnct_Distance, 0, 0);
-    sqlite3_create_function (db, "PtDistWithin", 3, SQLITE_ANY, cache,
-			     fnct_PtDistWithin, 0, 0);
-    sqlite3_create_function (db, "PtDistWithin", 4, SQLITE_ANY, cache,
-			     fnct_PtDistWithin, 0, 0);
-    sqlite3_create_function (db, "BdPolyFromText", 1, SQLITE_ANY, cache,
-			     fnct_BdPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "BdPolyFromText", 2, SQLITE_ANY, cache,
-			     fnct_BdPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "BdMPolyFromText", 1, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "BdMPolyFromText", 2, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "BdPolyFromWKB", 1, SQLITE_ANY, cache,
-			     fnct_BdPolyFromWKB1, 0, 0);
-    sqlite3_create_function (db, "BdPolyFromWKB", 2, SQLITE_ANY, cache,
-			     fnct_BdPolyFromWKB2, 0, 0);
-    sqlite3_create_function (db, "BdMPolyFromWKB", 1, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromWKB1, 0, 0);
-    sqlite3_create_function (db, "BdMPolyFromWKB", 2, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromWKB2, 0, 0);
-    sqlite3_create_function (db, "ST_BdPolyFromText", 1, SQLITE_ANY, cache,
-			     fnct_BdPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_BdPolyFromText", 2, SQLITE_ANY, cache,
-			     fnct_BdPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_BdMPolyFromText", 1, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromText1, 0, 0);
-    sqlite3_create_function (db, "ST_BdMPolyFromText", 2, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromText2, 0, 0);
-    sqlite3_create_function (db, "ST_BdPolyFromWKB", 1, SQLITE_ANY, cache,
-			     fnct_BdPolyFromWKB1, 0, 0);
-    sqlite3_create_function (db, "ST_BdPolyFromWKB", 2, SQLITE_ANY, cache,
-			     fnct_BdPolyFromWKB2, 0, 0);
-    sqlite3_create_function (db, "ST_BdMPolyFromWKB", 1, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromWKB1, 0, 0);
-    sqlite3_create_function (db, "ST_BdMPolyFromWKB", 2, SQLITE_ANY, cache,
-			     fnct_BdMPolyFromWKB2, 0, 0);
-    sqlite3_create_function (db, "CreateTopologyTables", 2, SQLITE_ANY, 0,
-			     fnct_CreateTopologyTables, 0, 0);
-    sqlite3_create_function (db, "CreateTopologyTables", 3, SQLITE_ANY, 0,
-			     fnct_CreateTopologyTables, 0, 0);
-    sqlite3_create_function (db, "OffsetCurve", 3, SQLITE_ANY, cache,
-			     fnct_OffsetCurve, 0, 0);
-    sqlite3_create_function (db, "ST_OffsetCurve", 3, SQLITE_ANY, cache,
-			     fnct_OffsetCurve, 0, 0);
-    sqlite3_create_function (db, "SingleSidedBuffer", 3, SQLITE_ANY, cache,
-			     fnct_SingleSidedBuffer, 0, 0);
-    sqlite3_create_function (db, "ST_SingleSidedBuffer", 3, SQLITE_ANY, cache,
-			     fnct_SingleSidedBuffer, 0, 0);
-    sqlite3_create_function (db, "HausdorffDistance", 2, SQLITE_ANY, cache,
-			     fnct_HausdorffDistance, 0, 0);
-    sqlite3_create_function (db, "ST_HausdorffDistance", 2, SQLITE_ANY, cache,
-			     fnct_HausdorffDistance, 0, 0);
-    sqlite3_create_function (db, "SharedPaths", 2, SQLITE_ANY, cache,
-			     fnct_SharedPaths, 0, 0);
-    sqlite3_create_function (db, "ST_SharedPaths", 2, SQLITE_ANY, cache,
-			     fnct_SharedPaths, 0, 0);
-    sqlite3_create_function (db, "Covers", 2, SQLITE_ANY, cache, fnct_Covers,
-			     0, 0);
-    sqlite3_create_function (db, "ST_Covers", 2, SQLITE_ANY, cache,
-			     fnct_Covers, 0, 0);
-    sqlite3_create_function (db, "CoveredBy", 2, SQLITE_ANY, cache,
-			     fnct_CoveredBy, 0, 0);
-    sqlite3_create_function (db, "ST_CoveredBy", 2, SQLITE_ANY, cache,
-			     fnct_CoveredBy, 0, 0);
-    sqlite3_create_function (db, "Line_Interpolate_Point", 2, SQLITE_ANY, cache,
-			     fnct_LineInterpolatePoint, 0, 0);
-    sqlite3_create_function (db, "ST_Line_Interpolate_Point", 2, SQLITE_ANY,
-			     cache, fnct_LineInterpolatePoint, 0, 0);
-    sqlite3_create_function (db, "Line_Interpolate_Equidistant_Points", 2,
-			     SQLITE_ANY, cache,
-			     fnct_LineInterpolateEquidistantPoints, 0, 0);
-    sqlite3_create_function (db, "ST_Line_Interpolate_Equidistant_Points", 2,
-			     SQLITE_ANY, cache,
-			     fnct_LineInterpolateEquidistantPoints, 0, 0);
-    sqlite3_create_function (db, "Line_Locate_Point", 2, SQLITE_ANY, cache,
-			     fnct_LineLocatePoint, 0, 0);
-    sqlite3_create_function (db, "ST_Line_Locate_Point", 2, SQLITE_ANY, cache,
-			     fnct_LineLocatePoint, 0, 0);
-    sqlite3_create_function (db, "Line_Substring", 3, SQLITE_ANY, cache,
-			     fnct_LineSubstring, 0, 0);
-    sqlite3_create_function (db, "ST_Line_Substring", 3, SQLITE_ANY, cache,
-			     fnct_LineSubstring, 0, 0);
-    sqlite3_create_function (db, "ClosestPoint", 2, SQLITE_ANY, cache,
-			     fnct_ClosestPoint, 0, 0);
-    sqlite3_create_function (db, "ST_ClosestPoint", 2, SQLITE_ANY, cache,
-			     fnct_ClosestPoint, 0, 0);
-    sqlite3_create_function (db, "ShortestLine", 2, SQLITE_ANY, cache,
-			     fnct_ShortestLine, 0, 0);
-    sqlite3_create_function (db, "ST_ShortestLine", 2, SQLITE_ANY, cache,
-			     fnct_ShortestLine, 0, 0);
-    sqlite3_create_function (db, "Snap", 3, SQLITE_ANY, cache, fnct_Snap, 0, 0);
-    sqlite3_create_function (db, "ST_Snap", 3, SQLITE_ANY, cache, fnct_Snap, 0,
-			     0);
-    sqlite3_create_function (db, "LineMerge", 1, SQLITE_ANY, cache,
-			     fnct_LineMerge, 0, 0);
-    sqlite3_create_function (db, "ST_LineMerge", 1, SQLITE_ANY, cache,
-			     fnct_LineMerge, 0, 0);
-    sqlite3_create_function (db, "UnaryUnion", 1, SQLITE_ANY, cache,
-			     fnct_UnaryUnion, 0, 0);
-    sqlite3_create_function (db, "ST_UnaryUnion", 1, SQLITE_ANY, cache,
-			     fnct_UnaryUnion, 0, 0);
-    sqlite3_create_function (db, "SquareGrid", 2, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "SquareGrid", 3, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "SquareGrid", 4, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SquareGrid", 2, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SquareGrid", 3, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "ST_SquareGrid", 4, SQLITE_ANY, cache,
-			     fnct_SquareGrid, 0, 0);
-    sqlite3_create_function (db, "TriangularGrid", 2, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "TriangularGrid", 3, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "TriangularGrid", 4, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "ST_TriangularGrid", 2, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "ST_TriangularGrid", 3, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "ST_TriangularGrid", 4, SQLITE_ANY, cache,
-			     fnct_TriangularGrid, 0, 0);
-    sqlite3_create_function (db, "HexagonalGrid", 2, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "HexagonalGrid", 3, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "HexagonalGrid", 4, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "ST_HexagonalGrid", 2, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "ST_HexagonalGrid", 3, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "ST_HexagonalGrid", 4, SQLITE_ANY, cache,
-			     fnct_HexagonalGrid, 0, 0);
-    sqlite3_create_function (db, "LinesCutAtNodes", 2, SQLITE_ANY, 0,
-			     fnct_LinesCutAtNodes, 0, 0);
-    sqlite3_create_function (db, "ST_LinesCutAtNodes", 2, SQLITE_ANY, 0,
-			     fnct_LinesCutAtNodes, 0, 0);
-    sqlite3_create_function (db, "RingsCutAtNodes", 1, SQLITE_ANY, 0,
-			     fnct_RingsCutAtNodes, 0, 0);
-    sqlite3_create_function (db, "ST_RingsCutAtNodes", 1, SQLITE_ANY, 0,
-			     fnct_RingsCutAtNodes, 0, 0);
+    sqlite3_create_function_v2 (db, "GEOS_GetLastErrorMsg", 0, SQLITE_UTF8,
+				cache, fnct_GEOS_GetLastErrorMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GEOS_GetLastWarningMsg", 0, SQLITE_UTF8,
+				cache, fnct_GEOS_GetLastWarningMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GEOS_GetLastAuxErrorMsg", 0, SQLITE_UTF8,
+				cache, fnct_GEOS_GetLastAuxErrorMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GEOS_GetCriticalPointFromMsg", 0,
+				SQLITE_UTF8, cache,
+				fnct_GEOS_GetCriticalPointFromMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GEOS_GetCriticalPointFromMsg", 1,
+				SQLITE_UTF8, cache,
+				fnct_GEOS_GetCriticalPointFromMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidReason", 1, SQLITE_UTF8, cache,
+				fnct_IsValidReason, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsValidReason", 1, SQLITE_UTF8, cache,
+				fnct_IsValidReason, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidDetail", 1, SQLITE_UTF8, cache,
+				fnct_IsValidDetail, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsValidDetail", 1, SQLITE_UTF8, cache,
+				fnct_IsValidDetail, 0, 0, 0);
+
+    sqlite3_create_function_v2 (db, "Boundary", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Boundary, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Boundary", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Boundary, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsClosed", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsClosed, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsClosed", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsClosed, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsSimple", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsSimple, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsSimple", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsSimple, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsRing, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsRing", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsRing, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsValid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_IsValid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_IsValid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GLength", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Length, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GLength", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Length, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Length", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Length, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Length", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Length, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Perimeter", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Perimeter, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Perimeter", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Perimeter, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Perimeter", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Perimeter, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Perimeter", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Perimeter, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Area", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Area, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Area", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Area, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Centroid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Centroid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Centroid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Centroid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PointOnSurface", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_PointOnSurface, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_PointOnSurface", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_PointOnSurface, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Simplify", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Simplify, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Simplify", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Simplify, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Generalize", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Simplify, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SimplifyPreserveTopology", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SimplifyPreserveTopology, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SimplifyPreserveTopology", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SimplifyPreserveTopology, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ConvexHull", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConvexHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ConvexHull", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConvexHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Buffer", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Buffer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Buffer", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Buffer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Intersection", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Intersection, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Intersection", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Intersection, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GUnion", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Union_step, fnct_Union_final, 0);
+    sqlite3_create_function_v2 (db, "GUnion", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Union, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Union", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache, 0,
+				fnct_Union_step, fnct_Union_final, 0);
+    sqlite3_create_function_v2 (db, "ST_Union", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Union, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Difference", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Difference, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Difference", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Difference, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SymDifference", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SymDifference, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SymDifference", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SymDifference, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Equals", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Equals, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Equals", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Equals, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Intersects", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Intersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Intersects", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Intersects, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Disjoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Disjoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Disjoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Disjoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Overlaps", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Overlaps, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Overlaps", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Overlaps, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Crosses", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Crosses, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Crosses", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Crosses, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Touches", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Touches, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Touches", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Touches, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Within", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Within, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Within", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Within, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Contains", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Contains, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Contains", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Contains, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Relate", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Relate, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Relate", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Relate, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Distance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Distance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Distance", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Distance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Distance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Distance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Distance", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Distance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PtDistWithin", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_PtDistWithin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "PtDistWithin", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_PtDistWithin, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdMPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdMPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromWKB1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromWKB2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdMPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromWKB1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "BdMPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromWKB2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdMPolyFromText", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromText1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdMPolyFromText", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromText2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromWKB1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdPolyFromWKB2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdMPolyFromWKB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromWKB1, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_BdMPolyFromWKB", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_BdMPolyFromWKB2, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateTopologyTables", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateTopologyTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateTopologyTables", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateTopologyTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "OffsetCurve", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_OffsetCurve, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_OffsetCurve", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_OffsetCurve, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SingleSidedBuffer", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SingleSidedBuffer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SingleSidedBuffer", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SingleSidedBuffer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HausdorffDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HausdorffDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_HausdorffDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HausdorffDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SharedPaths", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SharedPaths, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SharedPaths", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SharedPaths, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Covers", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Covers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Covers", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Covers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CoveredBy", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_CoveredBy, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_CoveredBy", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_CoveredBy, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Line_Interpolate_Point", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineInterpolatePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Line_Interpolate_Point", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineInterpolatePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Line_Interpolate_Equidistant_Points", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineInterpolateEquidistantPoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Line_Interpolate_Equidistant_Points", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineInterpolateEquidistantPoints, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Line_Locate_Point", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineLocatePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Line_Locate_Point", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineLocatePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Line_Substring", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineSubstring, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Line_Substring", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineSubstring, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ClosestPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ClosestPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ClosestPoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ClosestPoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ShortestLine", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ShortestLine, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ShortestLine", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ShortestLine, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Snap", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Snap, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Snap", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_Snap, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LineMerge", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineMerge, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LineMerge", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_LineMerge, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "UnaryUnion", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_UnaryUnion, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_UnaryUnion", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_UnaryUnion, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SquareGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SquareGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SquareGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SquareGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SquareGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SquareGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_SquareGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "TriangularGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "TriangularGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "TriangularGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_TriangularGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_TriangularGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_TriangularGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_TriangularGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HexagonalGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HexagonalGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "HexagonalGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_HexagonalGrid", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_HexagonalGrid", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_HexagonalGrid", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_HexagonalGrid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LinesCutAtNodes", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesCutAtNodes, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_LinesCutAtNodes", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_LinesCutAtNodes, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RingsCutAtNodes", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RingsCutAtNodes, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_RingsCutAtNodes", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RingsCutAtNodes, 0, 0, 0);
 
 #ifdef GEOS_ADVANCED		/* GEOS advanced features - 3.4.0 */
 
-    sqlite3_create_function (db, "DelaunayTriangulation", 1, SQLITE_ANY, cache,
-			     fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "DelaunayTriangulation", 2, SQLITE_ANY, cache,
-			     fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "DelaunayTriangulation", 3, SQLITE_ANY, cache,
-			     fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "ST_DelaunayTriangulation", 1, SQLITE_ANY,
-			     cache, fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "ST_DelaunayTriangulation", 2, SQLITE_ANY,
-			     cache, fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "ST_DelaunayTriangulation", 3, SQLITE_ANY,
-			     cache, fnct_DelaunayTriangulation, 0, 0);
-    sqlite3_create_function (db, "VoronojDiagram", 1, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "VoronojDiagram", 2, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "VoronojDiagram", 3, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "VoronojDiagram", 4, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "ST_VoronojDiagram", 1, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "ST_VoronojDiagram", 2, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "ST_VoronojDiagram", 3, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "ST_VoronojDiagram", 4, SQLITE_ANY, cache,
-			     fnct_VoronojDiagram, 0, 0);
-    sqlite3_create_function (db, "ConcaveHull", 1, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ConcaveHull", 2, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ConcaveHull", 3, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ConcaveHull", 4, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ST_ConcaveHull", 1, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ST_ConcaveHull", 2, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ST_ConcaveHull", 3, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
-    sqlite3_create_function (db, "ST_ConcaveHull", 4, SQLITE_ANY, cache,
-			     fnct_ConcaveHull, 0, 0);
+    sqlite3_create_function_v2 (db, "DelaunayTriangulation", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DelaunayTriangulation", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "DelaunayTriangulation", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_DelaunayTriangulation", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_DelaunayTriangulation", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_DelaunayTriangulation", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_DelaunayTriangulation, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "VoronojDiagram", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "VoronojDiagram", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "VoronojDiagram", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "VoronojDiagram", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_VoronojDiagram", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_VoronojDiagram", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_VoronojDiagram", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_VoronojDiagram", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_VoronojDiagram, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ConcaveHull", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ConcaveHull", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ConcaveHull", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ConcaveHull", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ConcaveHull", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ConcaveHull", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ConcaveHull", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_ConcaveHull", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_ConcaveHull, 0, 0, 0);
 
 #endif /* end GEOS advanced features */
 
 #ifdef ENABLE_LWGEOM		/* enabling LWGEOM support */
 
-    sqlite3_create_function (db, "LWGEOM_GetLastErrorMsg", 0, SQLITE_ANY,
-			     0, fnct_LWGEOM_GetLastErrorMsg, 0, 0);
-    sqlite3_create_function (db, "LWGEOM_GetLastWarningMsg", 0, SQLITE_ANY,
-			     0, fnct_LWGEOM_GetLastWarningMsg, 0, 0);
-
-    sqlite3_create_function (db, "MakeValid", 1, SQLITE_ANY, 0,
-			     fnct_MakeValid, 0, 0);
-    sqlite3_create_function (db, "ST_MakeValid", 1, SQLITE_ANY, 0,
-			     fnct_MakeValid, 0, 0);
-    sqlite3_create_function (db, "MakeValidDiscarded", 1, SQLITE_ANY, 0,
-			     fnct_MakeValidDiscarded, 0, 0);
-    sqlite3_create_function (db, "ST_MakeValidDiscarded", 1, SQLITE_ANY, 0,
-			     fnct_MakeValidDiscarded, 0, 0);
-    sqlite3_create_function (db, "Area", 2, SQLITE_ANY, 0, fnct_Area, 0, 0);
-    sqlite3_create_function (db, "ST_Area", 2, SQLITE_ANY, 0, fnct_Area, 0, 0);
-    sqlite3_create_function (db, "Segmentize", 2, SQLITE_ANY, 0,
-			     fnct_Segmentize, 0, 0);
-    sqlite3_create_function (db, "ST_Segmentize", 2, SQLITE_ANY, 0,
-			     fnct_Segmentize, 0, 0);
-    sqlite3_create_function (db, "Azimuth", 2, SQLITE_ANY, 0, fnct_Azimuth, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Azimuth", 2, SQLITE_ANY, 0, fnct_Azimuth,
-			     0, 0);
-    sqlite3_create_function (db, "Project", 3, SQLITE_ANY, 0, fnct_Project, 0,
-			     0);
-    sqlite3_create_function (db, "ST_Project", 3, SQLITE_ANY, 0, fnct_Project,
-			     0, 0);
-    sqlite3_create_function (db, "GeoHash", 1, SQLITE_ANY, 0, fnct_GeoHash, 0,
-			     0);
-    sqlite3_create_function (db, "GeoHash", 2, SQLITE_ANY, 0, fnct_GeoHash, 0,
-			     0);
-    sqlite3_create_function (db, "ST_GeoHash", 1, SQLITE_ANY, 0, fnct_GeoHash,
-			     0, 0);
-    sqlite3_create_function (db, "ST_GeoHash", 2, SQLITE_ANY, 0, fnct_GeoHash,
-			     0, 0);
-    sqlite3_create_function (db, "AsX3D", 1, SQLITE_ANY, 0, fnct_AsX3D, 0, 0);
-    sqlite3_create_function (db, "AsX3D", 2, SQLITE_ANY, 0, fnct_AsX3D, 0, 0);
-    sqlite3_create_function (db, "AsX3D", 3, SQLITE_ANY, 0, fnct_AsX3D, 0, 0);
-    sqlite3_create_function (db, "AsX3D", 4, SQLITE_ANY, 0, fnct_AsX3D, 0, 0);
-    sqlite3_create_function (db, "ST_AsX3D", 1, SQLITE_ANY, 0, fnct_AsX3D,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AsX3D", 2, SQLITE_ANY, 0, fnct_AsX3D,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AsX3D", 3, SQLITE_ANY, 0, fnct_AsX3D,
-			     0, 0);
-    sqlite3_create_function (db, "ST_AsX3D", 4, SQLITE_ANY, 0, fnct_AsX3D,
-			     0, 0);
-    sqlite3_create_function (db, "ST_3DDistance", 2, SQLITE_ANY, 0,
-			     fnct_3DDistance, 0, 0);
-    sqlite3_create_function (db, "MaxDistance", 2, SQLITE_ANY, 0,
-			     fnct_MaxDistance, 0, 0);
-    sqlite3_create_function (db, "ST_MaxDistance", 2, SQLITE_ANY, 0,
-			     fnct_MaxDistance, 0, 0);
-    sqlite3_create_function (db, "ST_3DMaxDistance", 2, SQLITE_ANY, 0,
-			     fnct_3DMaxDistance, 0, 0);
-    sqlite3_create_function (db, "Split", 2, SQLITE_ANY, 0, fnct_Split, 0, 0);
-    sqlite3_create_function (db, "ST_Split", 2, SQLITE_ANY, 0, fnct_Split,
-			     0, 0);
-    sqlite3_create_function (db, "SplitLeft", 2, SQLITE_ANY, 0,
-			     fnct_SplitLeft, 0, 0);
-    sqlite3_create_function (db, "ST_SplitLeft", 2, SQLITE_ANY, 0,
-			     fnct_SplitLeft, 0, 0);
-    sqlite3_create_function (db, "SplitRight", 2, SQLITE_ANY, 0,
-			     fnct_SplitRight, 0, 0);
-    sqlite3_create_function (db, "ST_SplitRight", 2, SQLITE_ANY, 0,
-			     fnct_SplitRight, 0, 0);
-    sqlite3_create_function (db, "ST_Node", 1, SQLITE_ANY, 0, fnct_Node, 0, 0);
-    sqlite3_create_function (db, "SelfIntersections", 1, SQLITE_ANY, 0,
-			     fnct_SelfIntersections, 0, 0);
-    sqlite3_create_function (db, "ST_SelfIntersections", 1, SQLITE_ANY, 0,
-			     fnct_SelfIntersections, 0, 0);
+    sqlite3_create_function_v2 (db, "LWGEOM_GetLastErrorMsg", 0, SQLITE_UTF8,
+				0, fnct_LWGEOM_GetLastErrorMsg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "LWGEOM_GetLastWarningMsg", 0, SQLITE_UTF8,
+				0, fnct_LWGEOM_GetLastWarningMsg, 0, 0, 0);
+
+    sqlite3_create_function_v2 (db, "MakeValid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeValid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MakeValid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeValid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MakeValidDiscarded", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeValidDiscarded, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MakeValidDiscarded", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MakeValidDiscarded, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Area", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Area, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Area", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Area, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Segmentize", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Segmentize, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Segmentize", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Segmentize, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Azimuth", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Azimuth, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Azimuth", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Azimuth, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Project", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Project, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Project", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Project, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeoHash", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeoHash, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeoHash", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeoHash, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeoHash", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeoHash, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_GeoHash", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeoHash, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsX3D", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsX3D", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsX3D", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsX3D", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsX3D", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsX3D", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsX3D", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_AsX3D", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AsX3D, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_3DDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_3DDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "MaxDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MaxDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_MaxDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_MaxDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_3DMaxDistance", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_3DMaxDistance, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "Split", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Split, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Split", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Split, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SplitLeft", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SplitLeft, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SplitLeft", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SplitLeft, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SplitRight", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SplitRight, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SplitRight", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SplitRight, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_Node", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_Node, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SelfIntersections", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SelfIntersections, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "ST_SelfIntersections", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SelfIntersections, 0, 0, 0);
 
 #endif /* end LWGEOM support */
 
@@ -29755,176 +32388,255 @@ register_spatialite_sql_functions (void *p_db, const void *p_cache)
 
 #ifdef ENABLE_LIBXML2		/* including LIBXML2 */
 
-    sqlite3_create_function (db, "CreateStylingTables", 0, SQLITE_ANY, 0,
-			     fnct_CreateStylingTables, 0, 0);
-    sqlite3_create_function (db, "CreateStylingTables", 1, SQLITE_ANY, 0,
-			     fnct_CreateStylingTables, 0, 0);
-    sqlite3_create_function (db, "RegisterExternalGraphic", 2, SQLITE_ANY, 0,
-			     fnct_RegisterExternalGraphic, 0, 0);
-    sqlite3_create_function (db, "RegisterExternalGraphic", 5, SQLITE_ANY, 0,
-			     fnct_RegisterExternalGraphic, 0, 0);
-    sqlite3_create_function (db, "RegisterVectorStyledLayer", 3, SQLITE_ANY,
-			     0, fnct_RegisterVectorStyledLayer, 0, 0);
-    sqlite3_create_function (db, "RegisterVectorStyledLayer", 4, SQLITE_ANY,
-			     0, fnct_RegisterVectorStyledLayer, 0, 0);
-    sqlite3_create_function (db, "RegisterRasterStyledLayer", 2, SQLITE_ANY,
-			     0, fnct_RegisterRasterStyledLayer, 0, 0);
-    sqlite3_create_function (db, "RegisterRasterStyledLayer", 3, SQLITE_ANY,
-			     0, fnct_RegisterRasterStyledLayer, 0, 0);
-    sqlite3_create_function (db, "RegisterStyledGroup", 2, SQLITE_ANY, 0,
-			     fnct_RegisterStyledGroup, 0, 0);
-    sqlite3_create_function (db, "RegisterStyledGroup", 3, SQLITE_ANY, 0,
-			     fnct_RegisterStyledGroup, 0, 0);
-    sqlite3_create_function (db, "RegisterStyledGroup", 4, SQLITE_ANY, 0,
-			     fnct_RegisterStyledGroup, 0, 0);
-    sqlite3_create_function (db, "SetStyledGroupInfos", 3, SQLITE_ANY, 0,
-			     fnct_SetStyledGroupInfos, 0, 0);
-    sqlite3_create_function (db, "RegisterGroupStyle", 2, SQLITE_ANY,
-			     0, fnct_RegisterGroupStyle, 0, 0);
-    sqlite3_create_function (db, "RegisterGroupStyle", 3, SQLITE_ANY,
-			     0, fnct_RegisterGroupStyle, 0, 0);
-    sqlite3_create_function (db, "CreateIsoMetadataTables", 0, SQLITE_ANY, 0,
-			     fnct_CreateIsoMetadataTables, 0, 0);
-    sqlite3_create_function (db, "CreateIsoMetadataTables", 1, SQLITE_ANY, 0,
-			     fnct_CreateIsoMetadataTables, 0, 0);
-    sqlite3_create_function (db, "GetIsoMetadataId", 1, SQLITE_ANY, 0,
-			     fnct_GetIsoMetadataId, 0, 0);
-    sqlite3_create_function (db, "RegisterIsoMetadata", 2, SQLITE_ANY, 0,
-			     fnct_RegisterIsoMetadata, 0, 0);
-    sqlite3_create_function (db, "RegisterIsoMetadata", 3, SQLITE_ANY, 0,
-			     fnct_RegisterIsoMetadata, 0, 0);
-    sqlite3_create_function (db, "XB_Create", 1, SQLITE_ANY, cache,
-			     fnct_XB_Create, 0, 0);
-    sqlite3_create_function (db, "XB_Create", 2, SQLITE_ANY, cache,
-			     fnct_XB_Create, 0, 0);
-    sqlite3_create_function (db, "XB_Create", 3, SQLITE_ANY, cache,
-			     fnct_XB_Create, 0, 0);
-    sqlite3_create_function (db, "XB_GetPayload", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetPayload, 0, 0);
-    sqlite3_create_function (db, "XB_GetPayload", 2, SQLITE_ANY, 0,
-			     fnct_XB_GetPayload, 0, 0);
-    sqlite3_create_function (db, "XB_GetDocument", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetDocument, 0, 0);
-    sqlite3_create_function (db, "XB_GetDocument", 2, SQLITE_ANY, 0,
-			     fnct_XB_GetDocument, 0, 0);
-    sqlite3_create_function (db, "XB_SchemaValidate", 2, SQLITE_ANY, cache,
-			     fnct_XB_SchemaValidate, 0, 0);
-    sqlite3_create_function (db, "XB_Compress", 1, SQLITE_ANY, 0,
-			     fnct_XB_Compress, 0, 0);
-    sqlite3_create_function (db, "XB_Uncompress", 1, SQLITE_ANY, 0,
-			     fnct_XB_Uncompress, 0, 0);
-    sqlite3_create_function (db, "XB_IsValid", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsValid, 0, 0);
-    sqlite3_create_function (db, "XB_IsSchemaValidated", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsSchemaValidated, 0, 0);
-    sqlite3_create_function (db, "XB_IsCompressed", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsCompressed, 0, 0);
-    sqlite3_create_function (db, "XB_IsIsoMetadata", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsIsoMetadata, 0, 0);
-    sqlite3_create_function (db, "XB_IsSldSeVectorStyle", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsSldSeVectorStyle, 0, 0);
-    sqlite3_create_function (db, "XB_IsSldSeRasterStyle", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsSldSeRasterStyle, 0, 0);
-    sqlite3_create_function (db, "XB_IsSldStyle", 1, SQLITE_ANY, 0,
-			     fnct_XB_IsSldStyle, 0, 0);
-    sqlite3_create_function (db, "XB_IsSvg", 1, SQLITE_ANY, 0, fnct_XB_IsSvg,
-			     0, 0);
-    sqlite3_create_function (db, "XB_GetSchemaURI", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetSchemaURI, 0, 0);
-    sqlite3_create_function (db, "XB_GetInternalSchemaURI", 1, SQLITE_ANY,
-			     cache, fnct_XB_GetInternalSchemaURI, 0, 0);
-    sqlite3_create_function (db, "XB_GetFileId", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetFileId, 0, 0);
-    sqlite3_create_function (db, "XB_GetParentId", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetParentId, 0, 0);
-    sqlite3_create_function (db, "XB_SetFileId", 2, SQLITE_ANY, cache,
-			     fnct_XB_SetFileId, 0, 0);
-    sqlite3_create_function (db, "XB_SetParentId", 2, SQLITE_ANY, cache,
-			     fnct_XB_SetParentId, 0, 0);
-    sqlite3_create_function (db, "XB_AddFileId", 6, SQLITE_ANY, cache,
-			     fnct_XB_AddFileId, 0, 0);
-    sqlite3_create_function (db, "XB_AddParentId", 6, SQLITE_ANY, cache,
-			     fnct_XB_AddParentId, 0, 0);
-    sqlite3_create_function (db, "XB_GetName", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetName, 0, 0);
-    sqlite3_create_function (db, "XB_GetTitle", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetTitle, 0, 0);
-    sqlite3_create_function (db, "XB_GetAbstract", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetAbstract, 0, 0);
-    sqlite3_create_function (db, "XB_GetGeometry", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetGeometry, 0, 0);
-    sqlite3_create_function (db, "XB_GetDocumentSize", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetDocumentSize, 0, 0);
-    sqlite3_create_function (db, "XB_GetEncoding", 1, SQLITE_ANY, 0,
-			     fnct_XB_GetEncoding, 0, 0);
-    sqlite3_create_function (db, "XB_GetLastParseError", 0, SQLITE_ANY, cache,
-			     fnct_XB_GetLastParseError, 0, 0);
-    sqlite3_create_function (db, "XB_GetLastValidateError", 0, SQLITE_ANY,
-			     cache, fnct_XB_GetLastValidateError, 0, 0);
-    sqlite3_create_function (db, "XB_IsValidXPathExpression", 1, SQLITE_ANY,
-			     cache, fnct_XB_IsValidXPathExpression, 0, 0);
-    sqlite3_create_function (db, "XB_GetLastXPathError", 0, SQLITE_ANY, cache,
-			     fnct_XB_GetLastXPathError, 0, 0);
-    sqlite3_create_function (db, "XB_CacheFlush", 0, SQLITE_ANY, cache,
-			     fnct_XB_CacheFlush, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateStylingTables", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateStylingTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateStylingTables", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateStylingTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterExternalGraphic", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterExternalGraphic, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterExternalGraphic", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterExternalGraphic, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterVectorStyledLayer", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterVectorStyledLayer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterVectorStyledLayer", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterVectorStyledLayer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterRasterStyledLayer", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterRasterStyledLayer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterRasterStyledLayer", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterRasterStyledLayer, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterStyledGroup", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterStyledGroup, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterStyledGroup", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterStyledGroup, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterStyledGroup", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterStyledGroup, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "SetStyledGroupInfos", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_SetStyledGroupInfos, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterGroupStyle", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterGroupStyle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterGroupStyle", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterGroupStyle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateIsoMetadataTables", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateIsoMetadataTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CreateIsoMetadataTables", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CreateIsoMetadataTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GetIsoMetadataId", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GetIsoMetadataId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterIsoMetadata", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterIsoMetadata, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "RegisterIsoMetadata", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_RegisterIsoMetadata, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_Create", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_Create, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_Create", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_Create, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_Create", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_Create, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetPayload", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetPayload, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetPayload", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetPayload, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetDocument", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetDocument, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetDocument", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetDocument, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_SchemaValidate", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_SchemaValidate, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_Compress", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_Compress, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_Uncompress", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_Uncompress, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsValid", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsValid, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsSchemaValidated", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsSchemaValidated, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsCompressed", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsCompressed, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsIsoMetadata", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsIsoMetadata, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsSldSeVectorStyle", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsSldSeVectorStyle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsSldSeRasterStyle", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsSldSeRasterStyle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsSldStyle", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsSldStyle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsSvg", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_IsSvg, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetSchemaURI", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetSchemaURI, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetInternalSchemaURI", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_GetInternalSchemaURI, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetFileId", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetFileId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetParentId", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetParentId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_SetFileId", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_SetFileId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_SetParentId", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_SetParentId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_AddFileId", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_AddFileId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_AddParentId", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_AddParentId, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetName", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetName, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetTitle", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetTitle, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetAbstract", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetAbstract, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetGeometry", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetGeometry, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetDocumentSize", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetDocumentSize, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetEncoding", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_XB_GetEncoding, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetLastParseError", 0, SQLITE_UTF8,
+				cache, fnct_XB_GetLastParseError, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetLastValidateError", 0, SQLITE_UTF8,
+				cache, fnct_XB_GetLastValidateError, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_IsValidXPathExpression", 1, SQLITE_UTF8,
+				cache, fnct_XB_IsValidXPathExpression, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_GetLastXPathError", 0, SQLITE_UTF8,
+				cache, fnct_XB_GetLastXPathError, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "XB_CacheFlush", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, cache,
+				fnct_XB_CacheFlush, 0, 0, 0);
 
 #endif /* end including LIBXML2 */
 
 #ifdef ENABLE_GEOPACKAGE	/* enabling GeoPackage extensions */
 
-    sqlite3_create_function (db, "AutoGPKGStart", 0, SQLITE_ANY, 0,
-			     fnct_AutoGPKGStart, 0, 0);
-    sqlite3_create_function (db, "AutoGPKGStop", 0, SQLITE_ANY, 0,
-			     fnct_AutoGPKGStop, 0, 0);
+    sqlite3_create_function_v2 (db, "AutoGPKGStart", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AutoGPKGStart, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AutoGPKGStop", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_AutoGPKGStop, 0, 0, 0);
 
     /* not yet finalised geopackage raster functions, plus some convenience API */
-    sqlite3_create_function (db, "gpkgCreateBaseTables", 0, SQLITE_ANY, 0,
-			     fnct_gpkgCreateBaseTables, 0, 0);
-    sqlite3_create_function (db, "gpkgInsertEpsgSRID", 1, SQLITE_ANY, 0,
-			     fnct_gpkgInsertEpsgSRID, 0, 0);
-    sqlite3_create_function (db, "gpkgCreateTilesTable", 6, SQLITE_ANY, 0,
-			     fnct_gpkgCreateTilesTable, 0, 0);
-    sqlite3_create_function (db, "gpkgCreateTilesZoomLevel", 4, SQLITE_ANY, 0,
-			     fnct_gpkgCreateTilesZoomLevel, 0, 0);
-    sqlite3_create_function (db, "gpkgAddTileTriggers", 1, SQLITE_ANY, 0,
-			     fnct_gpkgAddTileTriggers, 0, 0);
-    sqlite3_create_function (db, "gpkgGetNormalZoom", 2, SQLITE_ANY, 0,
-			     fnct_gpkgGetNormalZoom, 0, 0);
-    sqlite3_create_function (db, "gpkgGetNormalRow", 3, SQLITE_ANY, 0,
-			     fnct_gpkgGetNormalRow, 0, 0);
-    sqlite3_create_function (db, "gpkgGetImageType", 1, SQLITE_ANY, 0,
-			     fnct_gpkgGetImageType, 0, 0);
-    sqlite3_create_function (db, "gpkgAddGeometryColumn", 6, SQLITE_ANY, 0,
-			     fnct_gpkgAddGeometryColumn, 0, 0);
-    sqlite3_create_function (db, "gpkgAddGeometryTriggers", 2, SQLITE_ANY, 0,
-			     fnct_gpkgAddGeometryTriggers, 0, 0);
-    sqlite3_create_function (db, "gpkgAddSpatialIndex", 2, SQLITE_ANY, 0,
-			     fnct_gpkgAddSpatialIndex, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePoint", 2, SQLITE_ANY, 0,
-			     fnct_gpkgMakePoint, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePoint", 3, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointWithSRID, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointZ", 3, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointZ, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointZ", 4, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointZWithSRID, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointM", 3, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointM, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointM", 4, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointMWithSRID, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointZM", 4, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointZM, 0, 0);
-    sqlite3_create_function (db, "gpkgMakePointZM", 5, SQLITE_ANY, 0,
-			     fnct_gpkgMakePointZMWithSRID, 0, 0);
-    sqlite3_create_function (db, "AsGPB", 1, SQLITE_ANY, 0, fnct_ToGPB, 0, 0);
-    sqlite3_create_function (db, "GeomFromGPB", 1, SQLITE_ANY, 0,
-			     fnct_GeomFromGPB, 0, 0);
-    sqlite3_create_function (db, "IsValidGPB", 1, SQLITE_ANY, 0,
-			     fnct_IsValidGPB, 0, 0);
-    sqlite3_create_function (db, "GPKG_IsAssignable", 2, SQLITE_ANY, 0,
-			     fnct_GPKG_IsAssignable, 0, 0);
-    sqlite3_create_function (db, "CastAutomagic", 1, SQLITE_ANY, 0,
-			     fnct_CastAutomagic, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgCreateBaseTables", 0,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgCreateBaseTables, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgInsertEpsgSRID", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgInsertEpsgSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgCreateTilesTable", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgCreateTilesTable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgCreateTilesZoomLevel", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgCreateTilesZoomLevel, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgAddTileTriggers", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgAddTileTriggers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgGetNormalZoom", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgGetNormalZoom, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgGetNormalRow", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgGetNormalRow, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgGetImageType", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgGetImageType, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgAddGeometryColumn", 6,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgAddGeometryColumn, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgAddGeometryTriggers", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgAddGeometryTriggers, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgAddSpatialIndex", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgAddSpatialIndex, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePoint", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePoint, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePoint", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointWithSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointZ", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointZ, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointZ", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointZWithSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointM", 3,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointM", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointMWithSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointZM", 4,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointZM, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "gpkgMakePointZM", 5,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_gpkgMakePointZMWithSRID, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "AsGPB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_ToGPB, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GeomFromGPB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GeomFromGPB, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "IsValidGPB", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_IsValidGPB, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "GPKG_IsAssignable", 2,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_GPKG_IsAssignable, 0, 0, 0);
+    sqlite3_create_function_v2 (db, "CastAutomagic", 1,
+				SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+				fnct_CastAutomagic, 0, 0, 0);
 
 #endif /* end enabling GeoPackage extensions */
 
@@ -29960,6 +32672,8 @@ init_spatialite_virtualtables (void *p_db, const void *p_cache)
     virtualbbox_extension_init (db, p_cache);
 /* initializing the VirtualSpatialIndex  extension */
     virtual_spatialindex_extension_init (db);
+/* initializing the VirtualElementary  extension */
+    virtual_elementary_extension_init (db);
 
 #ifdef ENABLE_GEOPACKAGE	/* only if GeoPackage support is enabled */
 /* initializing the VirtualFDO  extension */
@@ -30037,6 +32751,8 @@ spatialite_splash_screen (int verbose)
 		    ("\t- 'MbrCache'\t\t[Spatial Index - MBR cache]\n");
 		spatialite_i
 		    ("\t- 'VirtualSpatialIndex'\t[R*Tree metahandler]\n");
+		spatialite_i
+		    ("\t- 'VirtualElementary'\t[ElemGeoms metahandler]\n");
 
 #ifdef ENABLE_LIBXML2		/* VirtualXPath is supported */
 		spatialite_i
diff --git a/src/spatialite/statistics.c b/src/spatialite/statistics.c
index e6652b2..5be338b 100644
--- a/src/spatialite/statistics.c
+++ b/src/spatialite/statistics.c
@@ -1230,10 +1230,10 @@ do_compute_layer_statistics (sqlite3 * sqlite, const char *table,
     int ret;
     int error = 0;
     int count;
-    double min_x;
-    double min_y;
-    double max_x;
-    double max_y;
+    double min_x = DBL_MAX;
+    double min_y = DBL_MAX;
+    double max_x = 0.0 - DBL_MAX;
+    double max_y = 0.0 - DBL_MAX;
     int has_coords = 1;
     char *quoted;
     char *col_quoted;
diff --git a/src/spatialite/table_cloner.c b/src/spatialite/table_cloner.c
new file mode 100644
index 0000000..f46ba9f
--- /dev/null
+++ b/src/spatialite/table_cloner.c
@@ -0,0 +1,2318 @@
+/*
+
+ table_cloner.c -- Cloning a Table
+
+ version 4.2, 2014 August 23
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the SpatiaLite library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include "config-msvc.h"
+#else
+#include "config.h"
+#endif
+
+#include <spatialite/sqlite.h>
+#include <spatialite/debug.h>
+
+#include <spatialite.h>
+#include <spatialite_private.h>
+#include <spatialite/gaiaaux.h>
+
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#endif /* not WIN32 */
+
+struct aux_geometry
+{
+/* a Geometry column object */
+    int type;
+    int dims;
+    int srid;
+    int spatial_index;
+    int cast2multi;
+    int already_existing;
+};
+
+struct aux_trigger
+{
+/* a Trigger object */
+    char *name;
+    char *sql;
+    int already_existing;
+    struct aux_trigger *next;
+};
+
+struct aux_fk_columns
+{
+/* a Foreign Key Columns object */
+    char *from;
+    char *to;
+    struct aux_fk_columns *next;
+};
+
+struct aux_foreign_key
+{
+/* a Foreign Key object */
+    int id;
+    char *name;
+    char *references;
+    char *on_update;
+    char *on_delete;
+    char *match;
+    struct aux_fk_columns *first;
+    struct aux_fk_columns *last;
+    struct aux_foreign_key *next;
+};
+
+struct aux_index_column
+{
+/* an Index Column object */
+    char *name;
+    struct aux_index_column *next;
+};
+
+struct aux_index
+{
+/* a Table Index object */
+    char *name;
+    int unique;
+    struct aux_index_column *first;
+    struct aux_index_column *last;
+    struct aux_index *next;
+};
+
+struct aux_column
+{
+/* a Table Column object */
+    char *name;
+    char *type;
+    int notnull;
+    char *deflt;
+    int pk;
+    int fk;
+    int idx;
+    struct aux_geometry *geometry;
+    int ignore;
+    int already_existing;
+    int mismatching;
+    struct aux_column *next;
+};
+
+struct aux_pk_column
+{
+/* Primary Key Columns */
+    struct aux_column *column;
+    struct aux_pk_column *next;
+};
+
+struct aux_cloner
+{
+/* the main Cloner object */
+    sqlite3 *sqlite;
+    char *db_prefix;
+    char *in_table;
+    char *out_table;
+    struct aux_column *first_col;
+    struct aux_column *last_col;
+    struct aux_pk_column *first_pk;
+    struct aux_pk_column *last_pk;
+    struct aux_index *first_idx;
+    struct aux_index *last_idx;
+    struct aux_foreign_key *first_fk;
+    struct aux_foreign_key *last_fk;
+    struct aux_trigger *first_trigger;
+    struct aux_trigger *last_trigger;
+    struct aux_pk_column **sorted_pks;
+    int pk_count;
+    int autoincrement;
+    int resequence;
+    int with_fks;
+    int with_triggers;
+    int append;
+    int already_existing;
+};
+
+static int
+create_column (sqlite3 * sqlite, const char *table, struct aux_column *column)
+{
+/* creating a further ordinary Column */
+    char *sql;
+    char *err_msg = NULL;
+    int ret;
+    char *xtable;
+    char *xcolumn;
+
+    xtable = gaiaDoubleQuotedSql (table);
+    xcolumn = gaiaDoubleQuotedSql (column->name);
+    if (column->notnull)
+      {
+	  if (column->deflt != NULL)
+	      sql = sqlite3_mprintf ("ALTER TABLE main.\"%s\" "
+				     "ADD COLUMN \"%s\" %s NOT NULL DEFAULT %s",
+				     xtable, xcolumn, column->type,
+				     column->deflt);
+	  else
+	      sql = sqlite3_mprintf ("ALTER TABLE main.\"%s\" "
+				     "ADD COLUMN \"%s\" %s NOT NULL", xtable,
+				     xcolumn, column->type);
+      }
+    else
+      {
+	  if (column->deflt != NULL)
+	      sql = sqlite3_mprintf ("ALTER TABLE main.\"%s\" "
+				     "ADD COLUMN \"%s\" %s DEFAULT %s", xtable,
+				     xcolumn, column->type, column->deflt);
+	  else
+	      sql = sqlite3_mprintf ("ALTER TABLE main.\"%s\" "
+				     "ADD COLUMN \"%s\" %s", xtable, xcolumn,
+				     column->type);
+      }
+    free (xtable);
+    free (xcolumn);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("ALTER TABLE ADD COLUMN error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+create_geometry (sqlite3 * sqlite, const char *table, struct aux_column *column)
+{
+/* creating a further Geometry Column */
+    char *sql;
+    char *err_msg = NULL;
+    int ret;
+    char *xtable;
+    char *xcolumn;
+    const char *type = "GEOMETRY";
+    const char *dims = "XY";
+    int gtype = column->geometry->type;
+
+    if (column->geometry->cast2multi)
+      {
+	  /* promoting to the corresponding MultiType */
+	  switch (column->geometry->type)
+	    {
+	    case 1:
+		gtype = 4;
+		break;
+	    case 1001:
+		gtype = 1004;
+		break;
+	    case 2001:
+		gtype = 2004;
+		break;
+	    case 3001:
+		gtype = 3004;
+		break;
+	    case 2:
+		gtype = 5;
+		break;
+	    case 1002:
+		gtype = 1005;
+		break;
+	    case 2002:
+		gtype = 2005;
+		break;
+	    case 3002:
+		gtype = 3005;
+		break;
+	    case 3:
+		gtype = 6;
+		break;
+	    case 1003:
+		gtype = 1006;
+		break;
+	    case 2003:
+		gtype = 2006;
+		break;
+	    case 3003:
+		gtype = 3006;
+		break;
+	    };
+      }
+
+    switch (gtype)
+      {
+      case 1:
+	  type = "POINT";
+	  dims = "XY";
+	  break;
+      case 1001:
+	  type = "POINT";
+	  dims = "XYZ";
+	  break;
+      case 2001:
+	  type = "POINT";
+	  dims = "XYM";
+	  break;
+      case 3001:
+	  type = "POINT";
+	  dims = "XYZM";
+	  break;
+      case 2:
+	  type = "LINESTRING";
+	  dims = "XY";
+	  break;
+      case 1002:
+	  type = "LINESTRING";
+	  dims = "XYZ";
+	  break;
+      case 2002:
+	  type = "LINESTRING";
+	  dims = "XYM";
+	  break;
+      case 3002:
+	  type = "LINESTRING";
+	  dims = "XYZM";
+	  break;
+      case 3:
+	  type = "POLYGON";
+	  dims = "XY";
+	  break;
+      case 1003:
+	  type = "POLYGON";
+	  dims = "XYZ";
+	  break;
+      case 2003:
+	  type = "POLYGON";
+	  dims = "XYM";
+	  break;
+      case 3003:
+	  type = "POLYGON";
+	  dims = "XYZM";
+	  break;
+      case 4:
+	  type = "MULTIPOINT";
+	  dims = "XY";
+	  break;
+      case 1004:
+	  type = "MULTIPOINT";
+	  dims = "XYZ";
+	  break;
+      case 2004:
+	  type = "MULTIPOINT";
+	  dims = "XYM";
+	  break;
+      case 3004:
+	  type = "MULTIPOINT";
+	  dims = "XYZM";
+	  break;
+      case 5:
+	  type = "MULTILINESTRING";
+	  dims = "XY";
+	  break;
+      case 1005:
+	  type = "MULTILINESTRING";
+	  dims = "XYZ";
+	  break;
+      case 2005:
+	  type = "MULTILINESTRING";
+	  dims = "XYM";
+	  break;
+      case 3005:
+	  type = "MULTILINESTRING";
+	  dims = "XYZM";
+	  break;
+      case 6:
+	  type = "MULTIPOLYGON";
+	  dims = "XY";
+	  break;
+      case 1006:
+	  type = "MULTIPOLYGON";
+	  dims = "XYZ";
+	  break;
+      case 2006:
+	  type = "MULTIPOLYGON";
+	  dims = "XYM";
+	  break;
+      case 3006:
+	  type = "MULTIPOLYGON";
+	  dims = "XYZM";
+	  break;
+      case 7:
+	  type = "GEOMETRYCOLLECTION";
+	  dims = "XY";
+	  break;
+      case 1007:
+	  type = "GEOMETRYCOLLECTION";
+	  dims = "XYZ";
+	  break;
+      case 2007:
+	  type = "GEOMETRYCOLLECTION";
+	  dims = "XYM";
+	  break;
+      case 3007:
+	  type = "GEOMETRYCOLLECTION";
+	  dims = "XYZM";
+	  break;
+      case 0:
+	  type = "GEOMETRY";
+	  dims = "XY";
+	  break;
+      case 1000:
+	  type = "GEOMETRY";
+	  dims = "XYZ";
+	  break;
+      case 2000:
+	  type = "GEOMETRY";
+	  dims = "XYM";
+	  break;
+      case 3000:
+	  type = "GEOMETRY";
+	  dims = "XYZM";
+	  break;
+      };
+
+    xtable = gaiaDoubleQuotedSql (table);
+    xcolumn = gaiaDoubleQuotedSql (column->name);
+    if (column->notnull)
+      {
+	  sql = sqlite3_mprintf ("SELECT AddGeometryColumn(Lower(%Q), "
+				 "Lower(%Q), %d, %Q, %Q, 1)", xtable, xcolumn,
+				 column->geometry->srid, type, dims);
+      }
+    else
+      {
+	  sql = sqlite3_mprintf ("SELECT AddGeometryColumn(Lower(%Q), "
+				 "Lower(%Q), %d, %Q, %Q)", xtable, xcolumn,
+				 column->geometry->srid, type, dims);
+      }
+    free (xtable);
+    free (xcolumn);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("ADD GEOMETRY COLUMN error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    if (column->geometry->spatial_index)
+      {
+	  /* creating the corresponding Spatial Index */
+	  xtable = gaiaDoubleQuotedSql (table);
+	  xcolumn = gaiaDoubleQuotedSql (column->name);
+	  sql = sqlite3_mprintf ("SELECT CreateSpatialIndex("
+				 "Lower(%Q), Lower(%Q))", xtable, xcolumn);
+	  free (xtable);
+	  free (xcolumn);
+	  ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+	  if (ret != SQLITE_OK)
+	    {
+		spatialite_e ("CREATE SPATIAL INDEX error: %s\n", err_msg);
+		sqlite3_free (err_msg);
+		return 0;
+	    }
+      }
+    return 1;
+}
+
+static int
+upgrade_output_table (struct aux_cloner *cloner)
+{
+/* creating any new Column required by APPEND */
+    struct aux_column *column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		/* skipping columns marked to be ignored */
+		column = column->next;
+		continue;
+	    }
+	  if (column->already_existing == 0)
+	    {
+		if (column->geometry != NULL)
+		  {
+		      /* creating a Geometry */
+		      if (!create_geometry
+			  (cloner->sqlite, cloner->out_table, column))
+			{
+			    spatialite_e
+				("CloneTable: unable to ADD Geometry COLUMN \"%s\" on Table \"%s\"\n",
+				 column->name, cloner->out_table);
+			    return 0;
+			}
+		  }
+		else
+		  {
+		      /* creating an ordinary Column */
+		      if (!create_column
+			  (cloner->sqlite, cloner->out_table, column))
+			{
+			    spatialite_e
+				("CloneTable: unable to ADD COLUMN \"%s\" on Table \"%s\"\n",
+				 column->name, cloner->out_table);
+			    return 0;
+			}
+		  }
+	    }
+	  column = column->next;
+      }
+    return 1;
+}
+
+static void
+sort_pk_columns (struct aux_cloner *cloner)
+{
+/* sorting the PK columns (if required) */
+    struct aux_pk_column *ppk;
+    int cnt;
+    int ok;
+    if (cloner->pk_count <= 1)
+	return;
+    cloner->sorted_pks =
+	malloc (sizeof (struct aux_pk_column *) * cloner->pk_count);
+    cnt = 0;
+    ppk = cloner->first_pk;
+    while (ppk != NULL)
+      {
+	  /* copying pointers to PK cols */
+	  *(cloner->sorted_pks + cnt++) = ppk;
+	  ppk = ppk->next;
+      }
+    ok = 1;
+    while (ok)
+      {
+	  /* bubble sorting */
+	  ok = 0;
+	  for (cnt = 1; cnt < cloner->pk_count; cnt++)
+	    {
+		struct aux_pk_column *ppk1 = *(cloner->sorted_pks + cnt - 1);
+		ppk = *(cloner->sorted_pks + cnt);
+		if (ppk1->column->pk > ppk->column->pk)
+		  {
+		      /* swapping */
+		      *(cloner->sorted_pks + cnt - 1) = ppk;
+		      *(cloner->sorted_pks + cnt) = ppk1;
+		      ok = 1;
+		  }
+	    }
+      }
+}
+
+static void
+adjust_ignore (struct aux_cloner *cloner)
+{
+/* adjusting Ignore columns */
+    struct aux_column *column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		if (column->pk)
+		    column->ignore = 0;
+		if (column->fk && cloner->with_fks)
+		    column->ignore = 0;
+		if (column->idx)
+		    column->ignore = 0;
+	    }
+	  column = column->next;
+      }
+}
+
+static const char *
+get_pk_column (struct aux_cloner *cloner, int index)
+{
+/* returning a PK column name (by sorted index) */
+    struct aux_pk_column *ppk;
+    if (cloner->sorted_pks == NULL)
+	return NULL;
+    if (index < 0 || index >= cloner->pk_count)
+	return NULL;
+    ppk = *(cloner->sorted_pks + index);
+    return ppk->column->name;
+}
+
+static void
+mark_existing_trigger (struct aux_cloner *cloner, const char *name)
+{
+/* marking an existing Trigger */
+    struct aux_trigger *trigger = cloner->first_trigger;
+    while (trigger != NULL)
+      {
+	  if (strcasecmp (trigger->name, name) == 0)
+	    {
+		trigger->already_existing = 1;
+		return;
+	    }
+	  trigger = trigger->next;
+      }
+}
+
+static void
+check_existing_triggers (struct aux_cloner *cloner)
+{
+/* exploring the output table - already existing Triggers */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+
+    sql = sqlite3_mprintf ("SELECT name FROM main.sqlite_master "
+			   "WHERE type = 'trigger' AND Lower(tbl_name) = Lower(%Q)",
+			   cloner->in_table);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 0];
+		mark_existing_trigger (cloner, name);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static int
+create_output_table (struct aux_cloner *cloner)
+{
+/* creating the output Table */
+    char *err_msg = NULL;
+    int ret;
+    struct aux_column *column;
+    struct aux_foreign_key *fk;
+    struct aux_fk_columns *fk_col;
+    struct aux_index *index;
+    struct aux_index_column *idx_column;
+    char *sql;
+    char *prev_sql;
+    char *xtable;
+    char *xcolumn;
+    char *constraint;
+    char *xconstraint;
+    int first = 1;
+    int i;
+    int fk_no;
+
+    sort_pk_columns (cloner);
+    adjust_ignore (cloner);
+    xtable = gaiaDoubleQuotedSql (cloner->out_table);
+    sql = sqlite3_mprintf ("CREATE TABLE main.\"%s\"", xtable);
+    free (xtable);
+    prev_sql = sql;
+
+    column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		/* IGNORE requested */
+		column = column->next;
+		continue;
+	    }
+	  if (column->geometry != NULL)
+	    {
+		/* skipping any Geometry column */
+		column = column->next;
+		continue;
+	    }
+	  if (first)
+	    {
+		sql = sqlite3_mprintf ("%s (\n", prev_sql);
+		first = 0;
+	    }
+	  else
+	      sql = sqlite3_mprintf ("%s,\n", prev_sql);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  xcolumn = gaiaDoubleQuotedSql (column->name);
+	  if (cloner->pk_count == 1 && column->pk)
+	    {
+		/* immediately declaring a single column Primary Key */
+		if (cloner->autoincrement)
+		  {
+		      if (column->notnull)
+			{
+			    if (column->deflt != NULL)
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s NOT NULL PRIMARY KEY AUTOINCREMENT DEFAULT %s",
+				     prev_sql, xcolumn, column->type,
+				     column->deflt);
+			    else
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s NOT NULL PRIMARY KEY AUTOINCREMENT",
+				     prev_sql, xcolumn, column->type);
+			}
+		      else
+			{
+			    if (column->deflt != NULL)
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s PRIMARY KEY AUTOINCREMENT DEFAULT %s",
+				     prev_sql, xcolumn, column->type,
+				     column->deflt);
+			    else
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s PRIMARY KEY AUTOINCREMENT",
+				     prev_sql, xcolumn, column->type);
+			}
+		  }
+		else
+		  {
+		      if (column->notnull)
+			{
+			    if (column->deflt != NULL)
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s NOT NULL PRIMARY KEY DEFAULT %s",
+				     prev_sql, xcolumn, column->type,
+				     column->deflt);
+			    else
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s NOT NULL PRIMARY KEY",
+				     prev_sql, xcolumn, column->type);
+			}
+		      else
+			{
+			    if (column->deflt != NULL)
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s PRIMARY KEY DEFAULT %s",
+				     prev_sql, xcolumn, column->type,
+				     column->deflt);
+			    else
+				sql =
+				    sqlite3_mprintf
+				    ("%s\t\"%s\" %s PRIMARY KEY", prev_sql,
+				     xcolumn, column->type);
+			}
+		  }
+		free (xcolumn);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		column = column->next;
+		continue;
+	    }
+	  if (column->notnull)
+	    {
+		if (column->deflt != NULL)
+		    sql = sqlite3_mprintf ("%s\t\"%s\" %s NOT NULL DEFAULT %s",
+					   prev_sql, xcolumn, column->type,
+					   column->deflt);
+		else
+		    sql = sqlite3_mprintf ("%s\t\"%s\" %s NOT NULL",
+					   prev_sql, xcolumn, column->type);
+	    }
+	  else
+	    {
+		if (column->deflt != NULL)
+		    sql = sqlite3_mprintf ("%s\t\"%s\" %s DEFAULT %s",
+					   prev_sql, xcolumn, column->type,
+					   column->deflt);
+		else
+		    sql = sqlite3_mprintf ("%s\t\"%s\" %s",
+					   prev_sql, xcolumn, column->type);
+	    }
+	  free (xcolumn);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  column = column->next;
+      }
+
+    if (cloner->pk_count > 1)
+      {
+	  /* declaring a PRIMARY KEY CONSTRAINT */
+	  sql = sqlite3_mprintf ("%s,\n", prev_sql);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  constraint = sqlite3_mprintf ("pk_%s", cloner->out_table);
+	  xconstraint = gaiaDoubleQuotedSql (constraint);
+	  sqlite3_free (constraint);
+	  sql =
+	      sqlite3_mprintf ("%s\tCONSTRAINT \"%s\" PRIMARY KEY (", prev_sql,
+			       xconstraint);
+	  free (xconstraint);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  for (i = 0; i < cloner->pk_count; i++)
+	    {
+		xconstraint = gaiaDoubleQuotedSql (get_pk_column (cloner, i));
+		if (i == 0)
+		    sql = sqlite3_mprintf ("%s%s", prev_sql, xconstraint);
+		else
+		    sql = sqlite3_mprintf ("%s, %s", prev_sql, xconstraint);
+		free (xconstraint);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+	    }
+	  sql = sqlite3_mprintf ("%s)", prev_sql);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+      }
+
+    if (cloner->with_fks)
+      {
+	  /* cloning all Foreign Key definitions */
+	  fk = cloner->first_fk;
+	  fk_no = 1;
+	  while (fk != NULL)
+	    {
+		/* declaring all FOREIGN KEY CONSTRAINTs */
+		sql = sqlite3_mprintf ("%s,\n", prev_sql);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		constraint =
+		    sqlite3_mprintf ("fk_%s_%d", cloner->out_table, fk_no++);
+		xconstraint = gaiaDoubleQuotedSql (constraint);
+		sqlite3_free (constraint);
+		sql =
+		    sqlite3_mprintf ("%s\tCONSTRAINT \"%s\" FOREIGN KEY (",
+				     prev_sql, xconstraint);
+		free (xconstraint);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		fk_col = fk->first;
+		while (fk_col != NULL)
+		  {
+		      xconstraint = gaiaDoubleQuotedSql (fk_col->from);
+		      if (fk_col == fk->first)
+			  sql = sqlite3_mprintf ("%s%s", prev_sql, xconstraint);
+		      else
+			  sql =
+			      sqlite3_mprintf ("%s, %s", prev_sql, xconstraint);
+		      free (xconstraint);
+		      sqlite3_free (prev_sql);
+		      prev_sql = sql;
+		      fk_col = fk_col->next;
+		  }
+		xtable = gaiaDoubleQuotedSql (fk->references);
+		sql =
+		    sqlite3_mprintf ("%s) REFERENCES \"%s\" (", prev_sql,
+				     xtable);
+		free (xtable);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		fk_col = fk->first;
+		while (fk_col != NULL)
+		  {
+		      xconstraint = gaiaDoubleQuotedSql (fk_col->to);
+		      if (fk_col == fk->first)
+			  sql = sqlite3_mprintf ("%s%s", prev_sql, xconstraint);
+		      else
+			  sql =
+			      sqlite3_mprintf ("%s, %s", prev_sql, xconstraint);
+		      free (xconstraint);
+		      sqlite3_free (prev_sql);
+		      prev_sql = sql;
+		      fk_col = fk_col->next;
+		  }
+		sql = sqlite3_mprintf ("%s)", prev_sql);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		fk = fk->next;
+	    }
+      }
+    sql = sqlite3_mprintf ("%s\n)", prev_sql);
+    sqlite3_free (prev_sql);
+
+    ret = sqlite3_exec (cloner->sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("CREATE TABLE error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->geometry != NULL && !(column->ignore))
+	    {
+		/* adding a Geometry Column */
+		if (!create_geometry
+		    (cloner->sqlite, cloner->out_table, column))
+		    return 0;
+	    }
+	  column = column->next;
+      }
+
+    index = cloner->first_idx;
+    fk_no = 1;
+    while (index != NULL)
+      {
+	  /* creating an Index */
+	  constraint =
+	      sqlite3_mprintf ("idx_%s_%d", cloner->out_table, fk_no++);
+	  xconstraint = gaiaDoubleQuotedSql (constraint);
+	  xtable = gaiaDoubleQuotedSql (cloner->out_table);
+	  if (index->unique)
+	      sql =
+		  sqlite3_mprintf ("CREATE UNIQUE INDEX main.\"%s\" ON \"%s\"",
+				   xconstraint, xtable);
+	  else
+	      sql =
+		  sqlite3_mprintf ("CREATE INDEX main.\"%s\" ON \"%s\"",
+				   xconstraint, xtable);
+	  free (xconstraint);
+	  free (xtable);
+	  prev_sql = sql;
+
+	  idx_column = index->first;
+	  first = 1;
+	  while (idx_column != NULL)
+	    {
+		xcolumn = gaiaDoubleQuotedSql (idx_column->name);
+		if (first)
+		  {
+		      sql = sqlite3_mprintf ("%s (\"%s\"", prev_sql, xcolumn);
+		      first = 0;
+		  }
+		else
+		    sql = sqlite3_mprintf ("%s, \"%s\"", prev_sql, xcolumn);
+		free (xcolumn);
+		sqlite3_free (prev_sql);
+		prev_sql = sql;
+		idx_column = idx_column->next;
+	    }
+	  sql = sqlite3_mprintf ("%s)\n", prev_sql);
+	  sqlite3_free (prev_sql);
+
+	  ret = sqlite3_exec (cloner->sqlite, sql, NULL, NULL, &err_msg);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		spatialite_e ("CREATE INDEX error: %s\n", err_msg);
+		sqlite3_free (err_msg);
+		return 0;
+	    }
+	  index = index->next;
+      }
+
+    if (cloner->with_triggers)
+      {
+	  struct aux_trigger *trigger;
+	  check_existing_triggers (cloner);
+	  trigger = cloner->first_trigger;
+	  while (trigger != NULL)
+	    {
+		if (trigger->already_existing)
+		  {
+		      /* skipping already defined triggers */
+		      trigger = trigger->next;
+		      continue;
+		  }
+		/* adding a trigger */
+		ret =
+		    sqlite3_exec (cloner->sqlite, trigger->sql, NULL, NULL,
+				  &err_msg);
+		if (ret != SQLITE_OK)
+		  {
+		      spatialite_e ("CREATE TRIGGER error: %s\n", err_msg);
+		      sqlite3_free (err_msg);
+		      return 0;
+		  }
+		trigger = trigger->next;
+	    }
+      }
+    return 1;
+}
+
+static int
+copy_rows (struct aux_cloner *cloner)
+{
+/* copying all rows from the origin into the destination Table */
+    sqlite3_stmt *stmt_in = NULL;
+    sqlite3_stmt *stmt_out = NULL;
+    int ret;
+    struct aux_column *column;
+    char *sql;
+    char *prev_sql;
+    char *xcolumn;
+    char *xtable;
+    char *xdb_prefix;
+    int first = 1;
+
+/* composing the SELECT statement */
+    sql = sqlite3_mprintf ("SELECT ");
+    prev_sql = sql;
+    column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		/* skipping columns to be IGNORED */
+		column = column->next;
+		continue;
+	    }
+	  xcolumn = gaiaDoubleQuotedSql (column->name);
+	  if (first)
+	    {
+		sql = sqlite3_mprintf ("%s\"%s\"", prev_sql, xcolumn);
+		first = 0;
+	    }
+	  else
+	      sql = sqlite3_mprintf ("%s, \"%s\"", prev_sql, xcolumn);
+	  free (xcolumn);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  column = column->next;
+      }
+    xdb_prefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    xtable = gaiaDoubleQuotedSql (cloner->in_table);
+    sql =
+	sqlite3_mprintf ("%s FROM \"%s\".\"%s\"", prev_sql, xdb_prefix, xtable);
+    free (xdb_prefix);
+    free (xtable);
+/* compiling the SELECT FROM statement */
+    ret =
+	sqlite3_prepare_v2 (cloner->sqlite, sql, strlen (sql), &stmt_in, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("SELECT FROM: \"%s\"\n",
+			sqlite3_errmsg (cloner->sqlite));
+	  goto error;
+      }
+
+/* composing the INSERT INTO statement */
+    xtable = gaiaDoubleQuotedSql (cloner->out_table);
+    sql = sqlite3_mprintf ("INSERT INTO \"%s\" (", xtable);
+    free (xtable);
+    prev_sql = sql;
+    first = 1;
+    column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		/* skipping columns to be IGNORED */
+		column = column->next;
+		continue;
+	    }
+	  xcolumn = gaiaDoubleQuotedSql (column->name);
+	  if (first)
+	    {
+		sql = sqlite3_mprintf ("%s\"%s\"", prev_sql, xcolumn);
+		first = 0;
+	    }
+	  else
+	      sql = sqlite3_mprintf ("%s, \"%s\"", prev_sql, xcolumn);
+	  free (xcolumn);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  column = column->next;
+      }
+    sql = sqlite3_mprintf ("%s) VALUES (", prev_sql);
+    sqlite3_free (prev_sql);
+    prev_sql = sql;
+    first = 1;
+    column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->ignore)
+	    {
+		/* skipping columns to be IGNORED */
+		column = column->next;
+		continue;
+	    }
+	  if (column->geometry != NULL)
+	    {
+		/* Geometry column */
+		if (column->geometry->cast2multi)
+		  {
+		      /* casting to MultiType */
+		      const char *expr = "CastToMulti(?)";
+		      if (first)
+			{
+			    sql = sqlite3_mprintf ("%s%s", prev_sql, expr);
+			    first = 0;
+			}
+		      else
+			  sql = sqlite3_mprintf ("%s, %s", prev_sql, expr);
+		      sqlite3_free (prev_sql);
+		      prev_sql = sql;
+		      column = column->next;
+		      continue;
+		  }
+	    }
+	  if (first)
+	    {
+		sql = sqlite3_mprintf ("%s?", prev_sql);
+		first = 0;
+	    }
+	  else
+	      sql = sqlite3_mprintf ("%s, ?", prev_sql);
+	  sqlite3_free (prev_sql);
+	  prev_sql = sql;
+	  column = column->next;
+      }
+    sql = sqlite3_mprintf ("%s)", prev_sql);
+    sqlite3_free (prev_sql);
+/* compiling the INSERT INTO statement */
+    ret =
+	sqlite3_prepare_v2 (cloner->sqlite, sql, strlen (sql), &stmt_out, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  spatialite_e ("INSERT INTO: \"%s\"\n",
+			sqlite3_errmsg (cloner->sqlite));
+	  goto error;
+      }
+
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt_in);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		/* copying values between input and output tables */
+		int pos = 0;
+		sqlite3_reset (stmt_out);
+		sqlite3_clear_bindings (stmt_out);
+		column = cloner->first_col;
+		while (column != NULL)
+		  {
+		      if (column->ignore)
+			{
+			    /* skipping columns to be IGNORED */
+			    column = column->next;
+			    continue;
+			}
+		      if (cloner->resequence && cloner->pk_count == 1
+			  && cloner->autoincrement && column->pk)
+			{
+			    /* resequencing an AUTOINCREMENT PK */
+			    sqlite3_bind_null (stmt_out, pos + 1);
+			    pos++;
+			    column = column->next;
+			    continue;
+			}
+		      if (sqlite3_column_type (stmt_in, pos) == SQLITE_INTEGER)
+			  sqlite3_bind_int64 (stmt_out, pos + 1,
+					      sqlite3_column_int64 (stmt_in,
+								    pos));
+		      else if (sqlite3_column_type (stmt_in, pos) ==
+			       SQLITE_FLOAT)
+			  sqlite3_bind_double (stmt_out, pos + 1,
+					       sqlite3_column_double (stmt_in,
+								      pos));
+		      else if (sqlite3_column_type (stmt_in, pos) ==
+			       SQLITE_TEXT)
+			  sqlite3_bind_text (stmt_out, pos + 1,
+					     (const char *)
+					     sqlite3_column_text (stmt_in, pos),
+					     sqlite3_column_bytes (stmt_in,
+								   pos),
+					     SQLITE_STATIC);
+		      else if (sqlite3_column_type (stmt_in, pos) ==
+			       SQLITE_BLOB)
+			  sqlite3_bind_blob (stmt_out, pos + 1,
+					     sqlite3_column_blob (stmt_in, pos),
+					     sqlite3_column_bytes (stmt_in,
+								   pos),
+					     SQLITE_STATIC);
+		      else
+			  sqlite3_bind_null (stmt_out, pos + 1);
+		      pos++;
+		      column = column->next;
+		  }
+		/* inserting into the output table */
+		ret = sqlite3_step (stmt_out);
+		if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+		    ;
+		else
+		  {
+		      spatialite_e ("OUTPUT step error: <%s>\n",
+				    sqlite3_errmsg (cloner->sqlite));
+		      goto error;
+		  }
+	    }
+	  else
+	    {
+		spatialite_e ("INPUT step error: <%s>\n",
+			      sqlite3_errmsg (cloner->sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt_in);
+    sqlite3_finalize (stmt_out);
+    return 1;
+
+  error:
+    if (stmt_in != NULL)
+	sqlite3_finalize (stmt_in);
+    if (stmt_out != NULL)
+	sqlite3_finalize (stmt_out);
+    return 0;
+}
+
+static void
+add_geometry (struct aux_cloner *cloner, const char *name, int type, int dims,
+	      int srid, int spatial_index)
+{
+/* adding a Geometry Column definition */
+    struct aux_column *pc = cloner->first_col;
+    while (pc != NULL)
+      {
+	  if (strcasecmp (pc->name, name) == 0)
+	    {
+		struct aux_geometry *geom =
+		    malloc (sizeof (struct aux_geometry));
+		geom->type = type;
+		geom->dims = dims;
+		geom->srid = srid;
+		geom->spatial_index = spatial_index;
+		geom->cast2multi = 0;
+		geom->already_existing = 0;
+		if (pc->geometry != NULL)
+		    free (pc->geometry);
+		pc->geometry = geom;
+		return;
+	    }
+	  pc = pc->next;
+      }
+}
+
+static void
+mark_existing_geometry (struct aux_cloner *cloner, const char *name, int type,
+			int dims, int srid)
+{
+/* marking an existing Geometry Column definition */
+    struct aux_column *pc = cloner->first_col;
+    while (pc != NULL)
+      {
+	  if (strcasecmp (pc->name, name) == 0)
+	    {
+		if (pc->geometry == NULL)
+		  {
+		      /* gosh, it's not a Geometry */
+		      pc->mismatching = 1;
+		      return;
+		  }
+		if (pc->geometry->type == type && pc->geometry->dims == dims
+		    && pc->geometry->srid == srid)
+		  {
+		      /* matching arguments: confirmed */
+		      pc->geometry->already_existing = 1;
+		      return;
+		  }
+		/* different arguments: invalid */
+		pc->mismatching = 1;
+		return;
+	    }
+	  pc = pc->next;
+      }
+}
+
+static void
+add_trigger (struct aux_cloner *cloner, const char *name, const char *sql)
+{
+/* adding a Trigger definition */
+    int len;
+    struct aux_trigger *trigger = malloc (sizeof (struct aux_trigger));
+    len = strlen (name);
+    trigger->name = malloc (len + 1);
+    strcpy (trigger->name, name);
+    len = strlen (sql);
+    trigger->sql = malloc (len + 1);
+    strcpy (trigger->sql, sql);
+    trigger->already_existing = 0;
+    trigger->next = NULL;
+/* updating the linked list */
+    if (cloner->first_trigger == NULL)
+	cloner->first_trigger = trigger;
+    if (cloner->last_trigger != NULL)
+	cloner->last_trigger->next = trigger;
+    cloner->last_trigger = trigger;
+}
+
+static void
+add_fk_columns (struct aux_foreign_key *fk, struct aux_column *first_col,
+		const char *from, const char *to)
+{
+/* adding Columns correspondencies into a Foreign Key definition */
+    int len;
+    struct aux_column *column;
+    struct aux_fk_columns *col = malloc (sizeof (struct aux_fk_columns));
+    len = strlen (from);
+    col->from = malloc (len + 1);
+    strcpy (col->from, from);
+    len = strlen (to);
+    col->to = malloc (len + 1);
+    strcpy (col->to, to);
+    col->next = NULL;
+/* updating the linked list */
+    if (fk->first == NULL)
+	fk->first = col;
+    if (fk->last != NULL)
+	fk->last->next = col;
+    fk->last = col;
+/* marking the column as a Foreign Key */
+    column = first_col;
+    while (column != NULL)
+      {
+	  if (strcasecmp (column->name, from) == 0)
+	    {
+		column->fk = 1;
+		break;
+	    }
+	  column = column->next;
+      }
+}
+
+static void
+add_foreign_key (struct aux_cloner *cloner, int id, const char *references,
+		 const char *from, const char *to, const char *on_update,
+		 const char *on_delete, const char *match)
+{
+/* adding a Foreign Key definition */
+    int len;
+    struct aux_foreign_key *fk;
+    if (cloner->last_fk != NULL)
+      {
+	  if (cloner->last_fk->id == id)
+	    {
+		/* continuing with the latest FK */
+		add_fk_columns (cloner->last_fk, cloner->first_col, from, to);
+		return;
+	    }
+      }
+    fk = malloc (sizeof (struct aux_foreign_key));
+    fk->id = id;
+    fk->name = NULL;
+    len = strlen (references);
+    fk->references = malloc (len + 1);
+    strcpy (fk->references, references);
+    fk->on_update = NULL;
+    fk->on_delete = NULL;
+    fk->match = NULL;
+    if (on_update != NULL)
+      {
+	  len = strlen (on_update);
+	  fk->on_update = malloc (len + 1);
+	  strcpy (fk->on_update, on_update);
+      }
+    if (on_delete != NULL)
+      {
+	  len = strlen (on_delete);
+	  fk->on_delete = malloc (len + 1);
+	  strcpy (fk->on_delete, on_delete);
+      }
+    if (match != NULL)
+      {
+	  len = strlen (match);
+	  fk->match = malloc (len + 1);
+	  strcpy (fk->match, match);
+      }
+    fk->first = NULL;
+    fk->last = NULL;
+    fk->next = NULL;
+    add_fk_columns (fk, cloner->first_col, from, to);
+/* updating the linked list */
+    if (cloner->first_fk == NULL)
+	cloner->first_fk = fk;
+    if (cloner->last_fk != NULL)
+	cloner->last_fk->next = fk;
+    cloner->last_fk = fk;
+}
+
+static void
+add_index_column (struct aux_index *index, struct aux_column *first_col,
+		  const char *name)
+{
+/* adding a Column into an Index definition */
+    int len;
+    struct aux_column *col;
+    struct aux_index_column *column = malloc (sizeof (struct aux_index_column));
+    len = strlen (name);
+    column->name = malloc (len + 1);
+    strcpy (column->name, name);
+    column->next = NULL;
+/* updating the linked list */
+    if (index->first == NULL)
+	index->first = column;
+    if (index->last != NULL)
+	index->last->next = column;
+    index->last = column;
+/* marking the column as a Foreign Key */
+    col = first_col;
+    while (col != NULL)
+      {
+	  if (strcasecmp (col->name, name) == 0)
+	    {
+		col->idx = 1;
+		break;
+	    }
+	  col = col->next;
+      }
+}
+
+static struct aux_index *
+add_index (struct aux_cloner *cloner, const char *name, int unique)
+{
+/* adding an Index definition */
+    int len;
+    struct aux_index *index = malloc (sizeof (struct aux_index));
+    len = strlen (name);
+    index->name = malloc (len + 1);
+    strcpy (index->name, name);
+    index->unique = unique;
+    index->first = NULL;
+    index->last = NULL;
+    index->next = NULL;
+/* updating the linked list */
+    if (cloner->first_idx == NULL)
+	cloner->first_idx = index;
+    if (cloner->last_idx != NULL)
+	cloner->last_idx->next = index;
+    cloner->last_idx = index;
+    return index;
+}
+
+static void
+add_column (struct aux_cloner *cloner, const char *name, const char *type,
+	    int notnull, const char *deflt, int pk)
+{
+/* adding a Column definition */
+    int len;
+    struct aux_column *column = malloc (sizeof (struct aux_column));
+    len = strlen (name);
+    column->name = malloc (len + 1);
+    strcpy (column->name, name);
+    len = strlen (type);
+    column->type = malloc (len + 1);
+    strcpy (column->type, type);
+    column->notnull = notnull;
+    if (deflt == NULL)
+	column->deflt = NULL;
+    else
+      {
+	  len = strlen (deflt);
+	  column->deflt = malloc (len + 1);
+	  strcpy (column->deflt, deflt);
+      }
+    column->pk = pk;
+    column->fk = 0;
+    column->idx = 0;
+    column->geometry = NULL;
+    column->ignore = 0;
+    column->already_existing = 0;
+    column->mismatching = 0;
+    column->next = NULL;
+/* updating the linked list */
+    if (cloner->first_col == NULL)
+	cloner->first_col = column;
+    if (cloner->last_col != NULL)
+	cloner->last_col->next = column;
+    cloner->last_col = column;
+    if (pk)
+      {
+	  struct aux_pk_column *ppk = malloc (sizeof (struct aux_pk_column));
+	  ppk->column = column;
+	  ppk->next = NULL;
+	  /* updating the linked list */
+	  if (cloner->first_pk == NULL)
+	      cloner->first_pk = ppk;
+	  if (cloner->last_pk != NULL)
+	      cloner->last_pk->next = ppk;
+	  cloner->last_pk = ppk;
+	  cloner->pk_count += 1;
+      }
+}
+
+static void
+mark_existing_column (struct aux_cloner *cloner, const char *name)
+{
+/* marking an existing Column */
+    struct aux_column *column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (strcasecmp (column->name, name) == 0)
+	    {
+		column->already_existing = 1;
+		return;
+	    }
+	  column = column->next;
+      }
+}
+
+static int
+check_input_table_columns (struct aux_cloner *cloner)
+{
+/* exploring the input table - Columns */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    const char *type;
+    int notnull;
+    const char *deflt;
+    int pk;
+    char *xprefix;
+    char *xtable;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    xtable = gaiaDoubleQuotedSql (cloner->in_table);
+    sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(\"%s\")", xprefix, xtable);
+    free (xprefix);
+    free (xtable);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return 0;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 1];
+		type = results[(i * columns) + 2];
+		notnull = atoi (results[(i * columns) + 3]);
+		deflt = results[(i * columns) + 4];
+		pk = atoi (results[(i * columns) + 5]);
+		add_column (cloner, name, type, notnull, deflt, pk);
+	    }
+      }
+    sqlite3_free_table (results);
+
+    if (cloner->first_col == NULL)
+      {
+	  spatialite_e
+	      ("CloneTable: input table \"%s\".\"%s\" does not exist\n",
+	       cloner->db_prefix, cloner->in_table);
+	  goto error;
+      }
+    return 1;
+
+  error:
+    return 0;
+}
+
+static void
+check_input_table_autoincrement (struct aux_cloner *cloner)
+{
+/* exploring the input table AUTOINCREMENT property */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    char *xprefix;
+
+    if (cloner->pk_count != 1)
+	return;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    sql = sqlite3_mprintf ("SELECT Count(*) FROM \"%s\".sqlite_sequence "
+			   "WHERE Lower(name) = Lower(%Q)",
+			   xprefix, cloner->in_table);
+    free (xprefix);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		if (atoi (results[(i * columns) + 0]) > 0)
+		    cloner->autoincrement = 1;
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_output_table_columns (struct aux_cloner *cloner)
+{
+/* exploring the output table - Columns */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    char *xtable;
+
+    xtable = gaiaDoubleQuotedSql (cloner->out_table);
+    sql = sqlite3_mprintf ("PRAGMA main.table_info(\"%s\")", xtable);
+    free (xtable);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 1];
+		mark_existing_column (cloner, name);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+expand_index (struct aux_cloner *cloner, struct aux_index *index)
+{
+/* expanding an Index definitions */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    char *xprefix;
+    char *xindex;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    xindex = gaiaDoubleQuotedSql (index->name);
+    sql = sqlite3_mprintf ("PRAGMA \"%s\".index_info(\"%s\")", xprefix, xindex);
+    free (xprefix);
+    free (xindex);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 2];
+		add_index_column (index, cloner->first_col, name);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_input_table_index_defs (struct aux_cloner *cloner)
+{
+/* exploring the input table - Index definitions */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    int unique;
+    char *xprefix;
+    char *xtable;
+    struct aux_index *idx;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    xtable = gaiaDoubleQuotedSql (cloner->in_table);
+    sql = sqlite3_mprintf ("PRAGMA \"%s\".index_list(\"%s\")", xprefix, xtable);
+    free (xprefix);
+    free (xtable);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 1];
+		if (strncasecmp (name, "sqlite_autoindex_", 17) == 0)
+		  {
+		      /* ignoring any AUTOINDEX defined by SQLite */
+		      continue;
+		  }
+		unique = atoi (results[(i * columns) + 2]);
+		idx = add_index (cloner, name, unique);
+		expand_index (cloner, idx);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_input_table_foreign_keys (struct aux_cloner *cloner)
+{
+/* exploring the input table - Foreign Keys */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    int id;
+    const char *references;
+    const char *from;
+    const char *to;
+    const char *on_update;
+    const char *on_delete;
+    const char *match;
+    char *xprefix;
+    char *xtable;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    xtable = gaiaDoubleQuotedSql (cloner->in_table);
+    sql =
+	sqlite3_mprintf ("PRAGMA \"%s\".foreign_key_list(\"%s\")", xprefix,
+			 xtable);
+    free (xprefix);
+    free (xtable);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		id = atoi (results[(i * columns) + 0]);
+		references = results[(i * columns) + 2];
+		from = results[(i * columns) + 3];
+		to = results[(i * columns) + 4];
+		on_update = results[(i * columns) + 5];
+		on_delete = results[(i * columns) + 6];
+		match = results[(i * columns) + 7];
+		if (strcasecmp (on_update, "NO ACTION") == 0)
+		    on_update = NULL;
+		if (strcasecmp (on_delete, "NO ACTION") == 0)
+		    on_delete = NULL;
+		if (strcasecmp (match, "NONE") == 0)
+		    match = NULL;
+		add_foreign_key (cloner, id, references, from, to, on_update,
+				 on_delete, match);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_input_table_triggers (struct aux_cloner *cloner)
+{
+/* exploring the input table - Triggers */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    const char *sqlx;
+    char *xprefix;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    sql = sqlite3_mprintf ("SELECT name, sql FROM \"%s\".sqlite_master "
+			   "WHERE type = 'trigger' AND Lower(tbl_name) = Lower(%Q)",
+			   xprefix, cloner->in_table);
+    free (xprefix);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 0];
+		sqlx = results[(i * columns) + 1];
+		add_trigger (cloner, name, sqlx);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_input_table_geometries (struct aux_cloner *cloner)
+{
+/* exploring the input table - Geometries */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    int type;
+    int dims;
+    int srid;
+    int spatial_index;
+    char *xprefix;
+
+    xprefix = gaiaDoubleQuotedSql (cloner->db_prefix);
+    sql = sqlite3_mprintf ("SELECT f_geometry_column, geometry_type, "
+			   "coord_dimension, srid, spatial_index_enabled "
+			   "FROM \"%s\".geometry_columns "
+			   "WHERE Lower(f_table_name) = Lower(%Q)",
+			   xprefix, cloner->in_table);
+    free (xprefix);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 0];
+		type = atoi (results[(i * columns) + 1]);
+		dims = atoi (results[(i * columns) + 2]);
+		srid = atoi (results[(i * columns) + 3]);
+		spatial_index = atoi (results[(i * columns) + 4]);
+		add_geometry (cloner, name, type, dims, srid, spatial_index);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+check_output_table_geometries (struct aux_cloner *cloner)
+{
+/* exploring the output table - Geometries */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    const char *name;
+    int type;
+    int dims;
+    int srid;
+
+    sql = sqlite3_mprintf ("SELECT f_geometry_column, geometry_type, "
+			   "coord_dimension, srid, spatial_index_enabled "
+			   "FROM main.geometry_columns "
+			   "WHERE Lower(f_table_name) = Lower(%Q)",
+			   cloner->out_table);
+    ret =
+	sqlite3_get_table (cloner->sqlite, sql, &results, &rows, &columns,
+			   NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	    {
+		name = results[(i * columns) + 0];
+		type = atoi (results[(i * columns) + 1]);
+		dims = atoi (results[(i * columns) + 2]);
+		srid = atoi (results[(i * columns) + 3]);
+		mark_existing_geometry (cloner, name, type, dims, srid);
+	    }
+      }
+    sqlite3_free_table (results);
+}
+
+static void
+free_trigger (struct aux_trigger *trigger)
+{
+/* memory cleanup - destroying a Trigger object */
+    if (trigger == NULL)
+	return;
+    if (trigger->name != NULL)
+	free (trigger->name);
+    if (trigger->sql != NULL)
+	free (trigger->sql);
+    free (trigger);
+}
+
+static void
+free_fk_columns (struct aux_fk_columns *col)
+{
+/* memory cleanup - destroying a Foreign Key Columns object */
+    if (col == NULL)
+	return;
+    if (col->from != NULL)
+	free (col->from);
+    if (col->to != NULL)
+	free (col->to);
+    free (col);
+}
+
+static void
+free_foreign_key (struct aux_foreign_key *fk)
+{
+/* memory cleanup - destroying a Foreign Key object */
+    struct aux_fk_columns *pc;
+    struct aux_fk_columns *pcn;
+    if (fk == NULL)
+	return;
+    if (fk->name != NULL)
+	free (fk->name);
+    if (fk->references != NULL)
+	free (fk->references);
+    if (fk->on_update != NULL)
+	free (fk->on_update);
+    if (fk->on_delete != NULL)
+	free (fk->on_delete);
+    if (fk->match != NULL)
+	free (fk->match);
+    pc = fk->first;
+    while (pc != NULL)
+      {
+	  pcn = pc->next;
+	  free_fk_columns (pc);
+	  pc = pcn;
+      }
+    free (fk);
+}
+
+static void
+free_index_column (struct aux_index_column *column)
+{
+/* memory cleanup - destroying an Index Column object */
+    if (column == NULL)
+	return;
+    if (column->name != NULL)
+	free (column->name);
+    free (column);
+}
+
+static void
+free_index (struct aux_index *index)
+{
+/* memory cleanup - destroying an Index object */
+    struct aux_index_column *pc;
+    struct aux_index_column *pcn;
+    if (index == NULL)
+	return;
+    if (index->name != NULL)
+	free (index->name);
+    pc = index->first;
+    while (pc != NULL)
+      {
+	  pcn = pc->next;
+	  free_index_column (pc);
+	  pc = pcn;
+      }
+    free (index);
+}
+
+static void
+free_column (struct aux_column *column)
+{
+/* memory cleanup - destroying a Column object */
+    if (column == NULL)
+	return;
+    if (column->name != NULL)
+	free (column->name);
+    if (column->type != NULL)
+	free (column->type);
+    if (column->deflt != NULL)
+	free (column->deflt);
+    if (column->geometry != NULL)
+	free (column->geometry);
+    free (column);
+}
+
+static void
+free_cloner (struct aux_cloner *cloner)
+{
+/* memory cleanup - destroying a Cloner object */
+    struct aux_column *pc;
+    struct aux_column *pcn;
+    struct aux_pk_column *ppk;
+    struct aux_pk_column *ppkn;
+    struct aux_index *pi;
+    struct aux_index *pin;
+    struct aux_foreign_key *pfk;
+    struct aux_foreign_key *pfkn;
+    struct aux_trigger *ptrg;
+    struct aux_trigger *ptrgn;
+    if (cloner == NULL)
+	return;
+    if (cloner->db_prefix != NULL)
+	free (cloner->db_prefix);
+    if (cloner->in_table != NULL)
+	free (cloner->in_table);
+    if (cloner->out_table != NULL)
+	free (cloner->out_table);
+    pc = cloner->first_col;
+    while (pc != NULL)
+      {
+	  pcn = pc->next;
+	  free_column (pc);
+	  pc = pcn;
+      }
+    ppk = cloner->first_pk;
+    while (ppk != NULL)
+      {
+	  ppkn = ppk->next;
+	  free (ppk);
+	  ppk = ppkn;
+      }
+    pi = cloner->first_idx;
+    while (pi != NULL)
+      {
+	  pin = pi->next;
+	  free_index (pi);
+	  pi = pin;
+      }
+    pfk = cloner->first_fk;
+    while (pfk != NULL)
+      {
+	  pfkn = pfk->next;
+	  free_foreign_key (pfk);
+	  pfk = pfkn;
+      }
+    ptrg = cloner->first_trigger;
+    while (ptrg != NULL)
+      {
+	  ptrgn = ptrg->next;
+	  free_trigger (ptrg);
+	  ptrg = ptrgn;
+      }
+    if (cloner->sorted_pks != NULL)
+	free (cloner->sorted_pks);
+    free (cloner);
+}
+
+static int
+already_existing_table (sqlite3 * sqlite, const char *table)
+{
+/* testing if the target Table is already defined */
+    char *sql;
+    int ret;
+    int i;
+    char **results;
+    int rows;
+    int columns;
+    int count = 0;
+
+    sql = sqlite3_mprintf ("SELECT Count(*) FROM main.sqlite_master "
+			   "WHERE type = 'table' AND Lower(name) = Lower(%Q)",
+			   table);
+    ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto stop;
+    if (rows < 1)
+	;
+    else
+      {
+	  for (i = 1; i <= rows; i++)
+	      count = atoi (results[(i * columns) + 0]);
+      }
+    sqlite3_free_table (results);
+  stop:
+    return count;
+}
+
+SPATIALITE_PRIVATE const void *
+gaiaAuxClonerCreate (const void *sqlite, const char *db_prefix,
+		     const char *in_table, const char *out_table)
+{
+/* creating a Cloner object */
+    int len;
+    struct aux_cloner *cloner;
+    if (checkSpatialMetaData ((sqlite3 *) sqlite) < 3)
+      {
+	  spatialite_e ("CloneTable: obsolete DB-layout (< 4.0.0)\n");
+	  return NULL;
+      }
+
+    cloner = malloc (sizeof (struct aux_cloner));
+    if (cloner == NULL)
+	return NULL;
+    cloner->sqlite = (sqlite3 *) sqlite;
+    cloner->db_prefix = NULL;
+    cloner->in_table = NULL;
+    cloner->out_table = NULL;
+    len = strlen (db_prefix);
+    cloner->db_prefix = malloc (len + 1);
+    strcpy (cloner->db_prefix, db_prefix);
+    len = strlen (in_table);
+    cloner->in_table = malloc (len + 1);
+    strcpy (cloner->in_table, in_table);
+    len = strlen (out_table);
+    cloner->out_table = malloc (len + 1);
+    strcpy (cloner->out_table, out_table);
+    cloner->first_col = NULL;
+    cloner->last_col = NULL;
+    cloner->first_pk = NULL;
+    cloner->last_pk = NULL;
+    cloner->first_idx = NULL;
+    cloner->last_idx = NULL;
+    cloner->first_fk = NULL;
+    cloner->last_fk = NULL;
+    cloner->first_trigger = NULL;
+    cloner->last_trigger = NULL;
+    cloner->pk_count = 0;
+    cloner->sorted_pks = NULL;
+    cloner->autoincrement = 0;
+    cloner->resequence = 0;
+    cloner->with_fks = 0;
+    cloner->with_triggers = 0;
+    cloner->append = 0;
+    cloner->already_existing = 0;
+
+/* exploring the input table - Columns */
+    if (!check_input_table_columns (cloner))
+	goto error;
+/* exploring PRIMARY KEY AUTOINCREMENT */
+    check_input_table_autoincrement (cloner);
+/* exploring the input table - Index definitions */
+    check_input_table_index_defs (cloner);
+/* exploring the input table - Foreign Key definitions */
+    check_input_table_foreign_keys (cloner);
+/* exploring the input table - Trigger definitions */
+    check_input_table_triggers (cloner);
+/* exploring the input table - Geometry definitions */
+    check_input_table_geometries (cloner);
+
+    if (already_existing_table (cloner->sqlite, out_table))
+	cloner->already_existing = 1;
+    return cloner;
+  error:
+    free_cloner (cloner);
+    return NULL;
+}
+
+SPATIALITE_PRIVATE void
+gaiaAuxClonerDestroy (const void *handle)
+{
+/* destroying a Cloner object */
+    struct aux_cloner *cloner = (struct aux_cloner *) handle;
+    if (handle == NULL)
+	return;
+    free_cloner (cloner);
+}
+
+static void
+ignore_column (struct aux_cloner *cloner, const char *column)
+{
+/* marking a Column to be ignored */
+    struct aux_column *pc = cloner->first_col;
+    while (pc != NULL)
+      {
+	  if (strcasecmp (pc->name, column) == 0)
+	    {
+		pc->ignore = 1;
+		return;
+	    }
+	  pc = pc->next;
+      }
+}
+
+static int
+check_append (struct aux_cloner *cloner)
+{
+/* cheching for APPEND validity */
+    int error = 0;
+    struct aux_column *column = cloner->first_col;
+    while (column != NULL)
+      {
+	  if (column->mismatching)
+	      error = 1;
+	  column = column->next;
+      }
+    if (error)
+	return 0;
+    return 1;
+}
+
+static void
+cast2multi_column (struct aux_cloner *cloner, const char *column)
+{
+/* marking a Geometry Column to be casted to MultiType */
+    struct aux_column *pc = cloner->first_col;
+    while (pc != NULL)
+      {
+	  if (strcasecmp (pc->name, column) == 0 && pc->geometry != NULL)
+	    {
+		pc->geometry->cast2multi = 1;
+		return;
+	    }
+	  pc = pc->next;
+      }
+}
+
+SPATIALITE_PRIVATE void
+gaiaAuxClonerAddOption (const void *handle, const char *option)
+{
+/* parsing an Option */
+    struct aux_cloner *cloner = (struct aux_cloner *) handle;
+    if (handle == NULL)
+	return;
+    if (strncasecmp (option, "::ignore::", 10) == 0)
+	ignore_column (cloner, option + 10);
+    if (strncasecmp (option, "::cast2multi::", 14) == 0)
+	cast2multi_column (cloner, option + 14);
+    if (strncasecmp (option, "::resequence::", 14) == 0)
+	cloner->resequence = 1;
+    if (strncasecmp (option, "::with-foreign-keys::", 21) == 0)
+	cloner->with_fks = 1;
+    if (strncasecmp (option, "::with-triggers::", 17) == 0)
+	cloner->with_triggers = 1;
+    if (strncasecmp (option, "::append::", 10) == 0)
+      {
+	  cloner->append = 1;
+	  cloner->resequence = 1;
+      }
+    return;
+}
+
+SPATIALITE_PRIVATE int
+gaiaAuxClonerCheckValidTarget (const void *handle)
+{
+/* checking the Target Table for validity */
+    struct aux_cloner *cloner = (struct aux_cloner *) handle;
+    if (handle == NULL)
+	return 0;
+
+    if (cloner->already_existing)
+      {
+	  if (cloner->append)
+	    {
+		/* exploring the output table - Columns */
+		check_output_table_columns (cloner);
+		/* exploring the output table - Geometries */
+		check_output_table_geometries (cloner);
+		/* checking for validity */
+		if (!check_append (cloner))
+		  {
+		      spatialite_e
+			  ("CloneTable: output table \"%s\" can't support APPEND\n",
+			   cloner->out_table);
+		      return 0;
+		  }
+	    }
+	  else
+	    {
+		spatialite_e
+		    ("CloneTable: output table \"%s\" already exists and APPEND is not enabled\n",
+		     cloner->out_table);
+		return 0;
+	    }
+      }
+    return 1;
+}
+
+SPATIALITE_PRIVATE int
+gaiaAuxClonerExecute (const void *handle)
+{
+/* executing the actual work */
+    struct aux_cloner *cloner = (struct aux_cloner *) handle;
+    if (handle == NULL)
+	return 0;
+    if (cloner->already_existing)
+      {
+	  /* creating any further column if required */
+	  if (!upgrade_output_table (cloner))
+	    {
+		spatialite_e
+		    ("CloneTable: unable to updgrade the output table \"%s\"\n",
+		     cloner->out_table);
+		return 0;
+	    }
+      }
+    else
+      {
+	  /* creating the output table */
+	  if (!create_output_table (cloner))
+	    {
+		spatialite_e
+		    ("CloneTable: unable to create the output table \"%s\"\n",
+		     cloner->out_table);
+		return 0;
+	    }
+      }
+    if (!copy_rows (cloner))
+      {
+	  spatialite_e ("CloneTable: unable to copy Table rows\n");
+	  return 0;
+      }
+    return 1;
+}
diff --git a/src/spatialite/virtualbbox.c b/src/spatialite/virtualbbox.c
index f70fce2..f4338c8 100644
--- a/src/spatialite/virtualbbox.c
+++ b/src/spatialite/virtualbbox.c
@@ -47,6 +47,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <float.h>
 
 #if defined(_WIN32) && !defined(__MINGW32__)
 #include "config-msvc.h"
@@ -302,10 +303,10 @@ vbbox_read_row (VirtualBBoxCursorPtr cursor)
     const unsigned char *blob;
     int size;
     sqlite3_int64 pk;
-    double minx;
-    double miny;
-    double maxx;
-    double maxy;
+    double minx = DBL_MAX;
+    double miny = DBL_MAX;
+    double maxx = 0.0 - DBL_MAX;
+    double maxy = 0.0 - DBL_MAX;
     int srid;
     char ok_minx = 'N';
     char ok_miny = 'N';
diff --git a/src/spatialite/virtualdbf.c b/src/spatialite/virtualdbf.c
index 44bfcb1..2ff1f61 100644
--- a/src/spatialite/virtualdbf.c
+++ b/src/spatialite/virtualdbf.c
@@ -77,6 +77,7 @@ typedef struct VirtualDbfStruct
     char *zErrMsg;		/* error message: USE INTERNALLY BY SQLITE */
     sqlite3 *db;		/* the sqlite db holding the virtual table */
     gaiaDbfPtr dbf;		/* the DBF struct */
+    int text_dates;
 } VirtualDbf;
 typedef VirtualDbf *VirtualDbfPtr;
 
@@ -123,13 +124,14 @@ vdbf_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
     int seed;
     int dup;
     int idup;
+    int text_dates = 0;
     char *xname;
     char **col_name = NULL;
     gaiaOutBuffer sql_statement;
     if (pAux)
 	pAux = pAux;		/* unused arg warning suppression */
 /* checking for DBF PATH */
-    if (argc == 5)
+    if (argc == 5 || argc == 6)
       {
 	  pPath = argv[3];
 	  len = strlen (pPath);
@@ -156,6 +158,8 @@ vdbf_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
 	    }
 	  else
 	      strcpy (encoding, pEncoding);
+	  if (argc == 6)
+	      text_dates = atoi (argv[5]);
       }
     else
       {
@@ -172,6 +176,7 @@ vdbf_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
     p_vt->zErrMsg = NULL;
     p_vt->db = db;
     p_vt->dbf = gaiaAllocDbf ();
+    p_vt->text_dates = text_dates;
 /* trying to open file */
     gaiaOpenDbfRead (p_vt->dbf, path, encoding, "UTF-8");
     if (!(p_vt->dbf->Valid))
@@ -239,6 +244,15 @@ vdbf_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
 	    }
 	  else if (pFld->Type == 'F')
 	      sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname);
+	  else if (pFld->Type == 'D')
+	    {
+		if (text_dates)
+		    sql =
+			sqlite3_mprintf (", \"%s\" VARCHAR(%d)", xname,
+					 pFld->Length);
+		else
+		    sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname);
+	    }
 	  else
 	      sql =
 		  sqlite3_mprintf (", \"%s\" VARCHAR(%d)", xname, pFld->Length);
@@ -344,7 +358,9 @@ vdbf_read_row (VirtualDbfCursorPtr cursor, int *deleted_row)
 	  cursor->eof = 1;
 	  return;
       }
-    ret = gaiaReadDbfEntity (cursor->pVtab->dbf, cursor->current_row, &deleted);
+    ret =
+	gaiaReadDbfEntity_ex (cursor->pVtab->dbf, cursor->current_row, &deleted,
+			      cursor->pVtab->text_dates);
     if (!ret)
       {
 	  if (!(cursor->pVtab->dbf->LastError))	/* normal DBF EOF */
diff --git a/src/spatialite/virtualelementary.c b/src/spatialite/virtualelementary.c
new file mode 100644
index 0000000..d7872b0
--- /dev/null
+++ b/src/spatialite/virtualelementary.c
@@ -0,0 +1,1063 @@
+/*
+
+ virtualelementary.c -- SQLite3 extension [VIRTUAL TABLE Elementary Geometries]
+
+ version 4.2, 2014 September 16
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the SpatiaLite library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include "config-msvc.h"
+#else
+#include "config.h"
+#endif
+
+#include <spatialite/sqlite.h>
+
+#include <spatialite/spatialite.h>
+#include <spatialite/gaiaaux.h>
+#include <spatialite/gaiageo.h>
+
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#define strncasecmp	_strnicmp
+#endif /* not WIN32 */
+
+static struct sqlite3_module my_elem_module;
+
+
+/******************************************************************************
+/
+/ VirtualTable structs
+/
+******************************************************************************/
+
+typedef struct VirtualElementaryStruct
+{
+/* extends the sqlite3_vtab struct */
+    const sqlite3_module *pModule;	/* ptr to sqlite module: USED INTERNALLY BY SQLITE */
+    int nRef;			/* # references: USED INTERNALLY BY SQLITE */
+    char *zErrMsg;		/* error message: USE INTERNALLY BY SQLITE */
+    sqlite3 *db;		/* the sqlite db holding the virtual table */
+} VirtualElementary;
+typedef VirtualElementary *VirtualElementaryPtr;
+
+typedef struct VirtualElementaryCursorStruct
+{
+/* extends the sqlite3_vtab_cursor struct */
+    VirtualElementaryPtr pVtab;	/* Virtual table of this cursor */
+    int eof;			/* the EOF marker */
+    char *db_prefix;
+    char *f_table_name;
+    char *f_geometry_column;
+    sqlite3_int64 origin_rowid;
+    gaiaGeomCollPtr *geometries;
+    int count;
+    int current;
+} VirtualElementaryCursor;
+typedef VirtualElementaryCursor *VirtualElementaryCursorPtr;
+
+static int
+velem_find_geometry (sqlite3 * sqlite, const char *db_prefix,
+		     const char *table_name, const char *geom_column,
+		     char **real_prefix, char **real_table, char **real_geom)
+{
+/* checks if the required Geometry actually defined */
+    sqlite3_stmt *stmt;
+    char *sql_statement;
+    int ret;
+    int count = 0;
+    char *rt = NULL;
+    char *rg = NULL;
+
+    if (geom_column == NULL)
+      {
+	  if (db_prefix == NULL)
+	    {
+		sql_statement =
+		    sqlite3_mprintf
+		    ("SELECT f_table_name, f_geometry_column FROM geometry_columns "
+		     "WHERE Upper(f_table_name) = Upper(%Q)", table_name);
+	    }
+	  else
+	    {
+		char *quoted_db = gaiaDoubleQuotedSql (db_prefix);
+		sql_statement =
+		    sqlite3_mprintf
+		    ("SELECT f_table_name, f_geometry_column FROM \"%s\".geometry_columns "
+		     "WHERE Upper(f_table_name) = Upper(%Q)",
+		     quoted_db, table_name);
+		free (quoted_db);
+	    }
+      }
+    else
+      {
+	  if (db_prefix == NULL)
+	    {
+		sql_statement =
+		    sqlite3_mprintf
+		    ("SELECT f_table_name, f_geometry_column FROM geometry_columns "
+		     "WHERE Upper(f_table_name) = Upper(%Q) AND "
+		     "Upper(f_geometry_column) = Upper(%Q)",
+		     table_name, geom_column);
+	    }
+	  else
+	    {
+		char *quoted_db = gaiaDoubleQuotedSql (db_prefix);
+		sql_statement =
+		    sqlite3_mprintf
+		    ("SELECT f_table_name, f_geometry_column FROM \"%s\".geometry_columns "
+		     "WHERE Upper(f_table_name) = Upper(%Q) AND "
+		     "Upper(f_geometry_column) = Upper(%Q)",
+		     quoted_db, table_name, geom_column);
+		free (quoted_db);
+	    }
+      }
+    ret =
+	sqlite3_prepare_v2 (sqlite, sql_statement, strlen (sql_statement),
+			    &stmt, NULL);
+    sqlite3_free (sql_statement);
+    if (ret != SQLITE_OK)
+	return 0;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *v = (const char *) sqlite3_column_text (stmt, 0);
+		int len = sqlite3_column_bytes (stmt, 0);
+		if (rt)
+		    free (rt);
+		rt = malloc (len + 1);
+		strcpy (rt, v);
+		v = (const char *) sqlite3_column_text (stmt, 1);
+		len = sqlite3_column_bytes (stmt, 1);
+		if (rg)
+		    free (rg);
+		rg = malloc (len + 1);
+		strcpy (rg, v);
+		count++;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return 0;
+    else
+      {
+	  int len;
+	  if (db_prefix == NULL)
+	      db_prefix = "main";
+	  len = strlen (db_prefix);
+	  *real_prefix = malloc (len + 1);
+	  strcpy (*real_prefix, db_prefix);
+	  *real_table = rt;
+	  *real_geom = rg;
+      }
+    return 1;
+}
+
+static gaiaGeomCollPtr
+velem_from_point (gaiaPointPtr pt, int srid)
+{
+/* creating a Geometry containing a single Point */
+    gaiaGeomCollPtr g = NULL;
+    switch (pt->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  g = gaiaAllocGeomCollXYZM ();
+	  break;
+      case GAIA_XY_Z:
+	  g = gaiaAllocGeomCollXYZ ();
+	  break;
+      case GAIA_XY_M:
+	  g = gaiaAllocGeomCollXYM ();
+	  break;
+      default:
+	  g = gaiaAllocGeomColl ();
+	  break;
+      };
+    if (!g)
+	return NULL;
+    g->Srid = srid;
+    g->DeclaredType = GAIA_POINT;
+    switch (pt->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  gaiaAddPointToGeomCollXYZM (g, pt->X, pt->Y, pt->Z, pt->M);
+	  break;
+      case GAIA_XY_Z:
+	  gaiaAddPointToGeomCollXYZ (g, pt->X, pt->Y, pt->Z);
+	  break;
+      case GAIA_XY_M:
+	  gaiaAddPointToGeomCollXYM (g, pt->X, pt->Y, pt->M);
+	  break;
+      default:
+	  gaiaAddPointToGeomColl (g, pt->X, pt->Y);
+	  break;
+      };
+    return g;
+}
+
+static gaiaGeomCollPtr
+velem_from_linestring (gaiaLinestringPtr ln, int srid)
+{
+/* creating a Geometry containing a single Linestring */
+    gaiaGeomCollPtr g = NULL;
+    gaiaLinestringPtr ln2;
+    int iv;
+    double x;
+    double y;
+    double z;
+    double m;
+    switch (ln->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  g = gaiaAllocGeomCollXYZM ();
+	  break;
+      case GAIA_XY_Z:
+	  g = gaiaAllocGeomCollXYZ ();
+	  break;
+      case GAIA_XY_M:
+	  g = gaiaAllocGeomCollXYM ();
+	  break;
+      default:
+	  g = gaiaAllocGeomColl ();
+	  break;
+      };
+    if (!g)
+	return NULL;
+    g->Srid = srid;
+    g->DeclaredType = GAIA_LINESTRING;
+    ln2 = gaiaAddLinestringToGeomColl (g, ln->Points);
+    switch (ln->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  for (iv = 0; iv < ln->Points; iv++)
+	    {
+		gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
+		gaiaSetPointXYZM (ln2->Coords, iv, x, y, z, m);
+	    }
+	  break;
+      case GAIA_XY_Z:
+	  for (iv = 0; iv < ln->Points; iv++)
+	    {
+		gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
+		gaiaSetPointXYZ (ln2->Coords, iv, x, y, z);
+	    }
+	  break;
+      case GAIA_XY_M:
+	  for (iv = 0; iv < ln->Points; iv++)
+	    {
+		gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
+		gaiaSetPointXYM (ln2->Coords, iv, x, y, m);
+	    }
+	  break;
+      default:
+	  for (iv = 0; iv < ln->Points; iv++)
+	    {
+		gaiaGetPoint (ln->Coords, iv, &x, &y);
+		gaiaSetPoint (ln2->Coords, iv, x, y);
+	    }
+	  break;
+      };
+    return g;
+}
+
+static gaiaGeomCollPtr
+velem_from_polygon (gaiaPolygonPtr pg, int srid)
+{
+/* creating a Geometry containing a single Polygon */
+    gaiaGeomCollPtr g = NULL;
+    gaiaPolygonPtr pg2;
+    gaiaRingPtr rng;
+    gaiaRingPtr rng2;
+    int ib;
+    int iv;
+    double x;
+    double y;
+    double z;
+    double m;
+    switch (pg->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  g = gaiaAllocGeomCollXYZM ();
+	  break;
+      case GAIA_XY_Z:
+	  g = gaiaAllocGeomCollXYZ ();
+	  break;
+      case GAIA_XY_M:
+	  g = gaiaAllocGeomCollXYM ();
+	  break;
+      default:
+	  g = gaiaAllocGeomColl ();
+	  break;
+      };
+    if (!g)
+	return NULL;
+    g->Srid = srid;
+    g->DeclaredType = GAIA_POLYGON;
+    rng = pg->Exterior;
+    pg2 = gaiaAddPolygonToGeomColl (g, rng->Points, pg->NumInteriors);
+    rng2 = pg2->Exterior;
+    switch (pg->DimensionModel)
+      {
+      case GAIA_XY_Z_M:
+	  for (iv = 0; iv < rng->Points; iv++)
+	    {
+		gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
+		gaiaSetPointXYZM (rng2->Coords, iv, x, y, z, m);
+	    }
+	  for (ib = 0; ib < pg->NumInteriors; ib++)
+	    {
+		rng = pg->Interiors + ib;
+		rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
+		for (iv = 0; iv < rng->Points; iv++)
+		  {
+		      gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
+		      gaiaSetPointXYZM (rng2->Coords, iv, x, y, z, m);
+		  }
+	    }
+	  break;
+      case GAIA_XY_Z:
+	  for (iv = 0; iv < rng->Points; iv++)
+	    {
+		gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
+		gaiaSetPointXYZ (rng2->Coords, iv, x, y, z);
+	    }
+	  for (ib = 0; ib < pg->NumInteriors; ib++)
+	    {
+		rng = pg->Interiors + ib;
+		rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
+		for (iv = 0; iv < rng->Points; iv++)
+		  {
+		      gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
+		      gaiaSetPointXYZ (rng2->Coords, iv, x, y, z);
+		  }
+	    }
+	  break;
+      case GAIA_XY_M:
+	  for (iv = 0; iv < rng->Points; iv++)
+	    {
+		gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
+		gaiaSetPointXYM (rng2->Coords, iv, x, y, m);
+	    }
+	  for (ib = 0; ib < pg->NumInteriors; ib++)
+	    {
+		rng = pg->Interiors + ib;
+		rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
+		for (iv = 0; iv < rng->Points; iv++)
+		  {
+		      gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
+		      gaiaSetPointXYM (rng2->Coords, iv, x, y, m);
+		  }
+	    }
+	  break;
+      default:
+	  for (iv = 0; iv < rng->Points; iv++)
+	    {
+		gaiaGetPoint (rng->Coords, iv, &x, &y);
+		gaiaSetPoint (rng2->Coords, iv, x, y);
+	    }
+	  for (ib = 0; ib < pg->NumInteriors; ib++)
+	    {
+		rng = pg->Interiors + ib;
+		rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
+		for (iv = 0; iv < rng->Points; iv++)
+		  {
+		      gaiaGetPoint (rng->Coords, iv, &x, &y);
+		      gaiaSetPoint (rng2->Coords, iv, x, y);
+		  }
+	    }
+	  break;
+      };
+    return g;
+}
+
+static int
+velem_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
+	      sqlite3_vtab ** ppVTab, char **pzErr)
+{
+/* creates the virtual table for Elementary Geometries metahandling */
+    VirtualElementaryPtr p_vt;
+    char *buf;
+    char *vtable;
+    char *xname;
+    if (pAux)
+	pAux = pAux;		/* unused arg warning suppression */
+    if (argc == 3)
+      {
+	  vtable = gaiaDequotedSql ((char *) argv[2]);
+      }
+    else
+      {
+	  *pzErr =
+	      sqlite3_mprintf
+	      ("[VirtualElementary module] CREATE VIRTUAL: illegal arg list {void}\n");
+	  return SQLITE_ERROR;
+      }
+    p_vt = (VirtualElementaryPtr) sqlite3_malloc (sizeof (VirtualElementary));
+    if (!p_vt)
+	return SQLITE_NOMEM;
+    p_vt->db = db;
+    p_vt->pModule = &my_elem_module;
+    p_vt->nRef = 0;
+    p_vt->zErrMsg = NULL;
+/* preparing the COLUMNs for this VIRTUAL TABLE */
+    xname = gaiaDoubleQuotedSql (vtable);
+    buf = sqlite3_mprintf ("CREATE TABLE \"%s\" (db_prefix TEXT, "
+			   "f_table_name TEXT, f_geometry_column TEXT, "
+			   "origin_rowid INTEGER, item_no INTEGER, geometry BLOB)",
+			   xname);
+    free (xname);
+    free (vtable);
+    if (sqlite3_declare_vtab (db, buf) != SQLITE_OK)
+      {
+	  sqlite3_free (buf);
+	  *pzErr =
+	      sqlite3_mprintf
+	      ("[VirtualElementary module] CREATE VIRTUAL: invalid SQL statement \"%s\"",
+	       buf);
+	  return SQLITE_ERROR;
+      }
+    sqlite3_free (buf);
+    *ppVTab = (sqlite3_vtab *) p_vt;
+    return SQLITE_OK;
+}
+
+static void
+velem_reset_cache (VirtualElementaryCursorPtr cursor)
+{
+/* cleaning the cursor's cache */
+    if (cursor->db_prefix != NULL)
+	free (cursor->db_prefix);
+    if (cursor->f_table_name != NULL)
+	free (cursor->f_table_name);
+    if (cursor->f_geometry_column != NULL)
+	free (cursor->f_geometry_column);
+    if (cursor->geometries != NULL)
+      {
+	  int i;
+	  for (i = 0; i < cursor->count; i++)
+	    {
+		gaiaGeomCollPtr geom = *(cursor->geometries + i);
+		gaiaFreeGeomColl (geom);
+	    }
+	  free (cursor->geometries);
+      }
+    cursor->db_prefix = NULL;
+    cursor->f_table_name = NULL;
+    cursor->f_geometry_column = NULL;
+    cursor->geometries = NULL;
+    cursor->count = 0;
+    cursor->current = 0;
+}
+
+static int
+velem_connect (sqlite3 * db, void *pAux, int argc, const char *const *argv,
+	       sqlite3_vtab ** ppVTab, char **pzErr)
+{
+/* connects the virtual table - simply aliases velem_create() */
+    return velem_create (db, pAux, argc, argv, ppVTab, pzErr);
+}
+
+static int
+velem_best_index (sqlite3_vtab * pVTab, sqlite3_index_info * pIdxInfo)
+{
+/* best index selection */
+    int i;
+    int errors = 0;
+    int err = 1;
+    int db_prefix = 0;
+    int table = 0;
+    int geom = 0;
+    int rowid = 0;
+    if (pVTab)
+	pVTab = pVTab;		/* unused arg warning suppression */
+    for (i = 0; i < pIdxInfo->nConstraint; i++)
+      {
+	  /* verifying the constraints */
+	  struct sqlite3_index_constraint *p = &(pIdxInfo->aConstraint[i]);
+	  if (p->usable)
+	    {
+		if (p->iColumn == 0 && p->op == SQLITE_INDEX_CONSTRAINT_EQ)
+		    db_prefix++;
+		else if (p->iColumn == 1 && p->op == SQLITE_INDEX_CONSTRAINT_EQ)
+		    table++;
+		else if (p->iColumn == 2 && p->op == SQLITE_INDEX_CONSTRAINT_EQ)
+		    geom++;
+		else if (p->iColumn == 3 && p->op == SQLITE_INDEX_CONSTRAINT_EQ)
+		    rowid++;
+		else
+		    errors++;
+	    }
+      }
+    if ((db_prefix == 0 || db_prefix == 1) && table == 1
+	&& (geom == 0 || geom == 1) && rowid == 1 && errors == 0)
+      {
+	  /* this one is a valid ElementaryGeometries query */
+	  if (db_prefix == 0)
+	    {
+		if (geom == 1)
+		    pIdxInfo->idxNum = 1;
+		else
+		    pIdxInfo->idxNum = 2;
+	    }
+	  else
+	    {
+		if (geom == 1)
+		    pIdxInfo->idxNum = 3;
+		else
+		    pIdxInfo->idxNum = 4;
+	    }
+	  pIdxInfo->estimatedCost = 1.0;
+	  for (i = 0; i < pIdxInfo->nConstraint; i++)
+	    {
+		if (pIdxInfo->aConstraint[i].usable)
+		  {
+		      pIdxInfo->aConstraintUsage[i].argvIndex = i + 1;
+		      pIdxInfo->aConstraintUsage[i].omit = 1;
+		  }
+	    }
+	  err = 0;
+      }
+    if (err)
+      {
+	  /* illegal query */
+	  pIdxInfo->idxNum = 0;
+      }
+    return SQLITE_OK;
+}
+
+static int
+velem_disconnect (sqlite3_vtab * pVTab)
+{
+/* disconnects the virtual table */
+    VirtualElementaryPtr p_vt = (VirtualElementaryPtr) pVTab;
+    sqlite3_free (p_vt);
+    return SQLITE_OK;
+}
+
+static int
+velem_destroy (sqlite3_vtab * pVTab)
+{
+/* destroys the virtual table - simply aliases velem_disconnect() */
+    return velem_disconnect (pVTab);
+}
+
+static int
+velem_open (sqlite3_vtab * pVTab, sqlite3_vtab_cursor ** ppCursor)
+{
+/* opening a new cursor */
+    VirtualElementaryCursorPtr cursor =
+	(VirtualElementaryCursorPtr)
+	sqlite3_malloc (sizeof (VirtualElementaryCursor));
+    if (cursor == NULL)
+	return SQLITE_ERROR;
+    cursor->pVtab = (VirtualElementaryPtr) pVTab;
+    cursor->eof = 1;
+    cursor->db_prefix = NULL;
+    cursor->f_table_name = NULL;
+    cursor->f_geometry_column = NULL;
+    cursor->geometries = NULL;
+    cursor->count = 0;
+    cursor->current = 0;
+    *ppCursor = (sqlite3_vtab_cursor *) cursor;
+    return SQLITE_OK;
+}
+
+static int
+velem_close (sqlite3_vtab_cursor * pCursor)
+{
+/* closing the cursor */
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    velem_reset_cache (cursor);
+    sqlite3_free (pCursor);
+    return SQLITE_OK;
+}
+
+static int
+velem_filter (sqlite3_vtab_cursor * pCursor, int idxNum, const char *idxStr,
+	      int argc, sqlite3_value ** argv)
+{
+/* setting up a cursor filter */
+    char *db_prefix = NULL;
+    char *table_name = NULL;
+    char *geom_column = NULL;
+    char *xprefix = NULL;
+    char *xtable = NULL;
+    char *xgeom = NULL;
+    char *table_nameQ;
+    char *geo_nameQ;
+    char *sql_statement;
+    sqlite3_int64 rowid_value;
+    int ok_prefix = 0;
+    int ok_table = 0;
+    int ok_geom = 0;
+    int ok_rowid = 0;
+    int exists;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    VirtualElementaryPtr elem = (VirtualElementaryPtr) cursor->pVtab;
+    if (idxStr)
+	idxStr = idxStr;	/* unused arg warning suppression */
+    cursor->eof = 1;
+    if (idxNum == 1 && argc == 3)
+      {
+	  /* retrieving the Table/Column/ROWID params */
+	  if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	    {
+		table_name = (char *) sqlite3_value_text (argv[0]);
+		ok_table = 1;
+	    }
+	  if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
+	    {
+		geom_column = (char *) sqlite3_value_text (argv[1]);
+		ok_geom = 1;
+	    }
+	  if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
+	    {
+		rowid_value = sqlite3_value_int64 (argv[2]);
+		ok_rowid = 1;
+	    }
+	  if (ok_table && ok_geom && ok_rowid)
+	      ;
+	  else
+	    {
+		/* invalid args */
+		goto stop;
+	    }
+      }
+    if (idxNum == 2 && argc == 2)
+      {
+	  /* retrieving the Table/ROWID params */
+	  if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	    {
+		table_name = (char *) sqlite3_value_text (argv[0]);
+		ok_table = 1;
+	    }
+	  if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
+	    {
+		rowid_value = sqlite3_value_int64 (argv[1]);
+		ok_rowid = 1;
+	    }
+	  if (ok_table && ok_rowid)
+	      ;
+	  else
+	    {
+		/* invalid args */
+		goto stop;
+	    }
+      }
+    if (idxNum == 3 && argc == 4)
+      {
+	  /* retrieving the DbPrefix/Table/Column/ROWID params */
+	  if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	    {
+		db_prefix = (char *) sqlite3_value_text (argv[0]);
+		ok_prefix = 1;
+	    }
+	  if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
+	    {
+		table_name = (char *) sqlite3_value_text (argv[1]);
+		ok_table = 1;
+	    }
+	  if (sqlite3_value_type (argv[2]) == SQLITE_TEXT)
+	    {
+		geom_column = (char *) sqlite3_value_text (argv[2]);
+		ok_geom = 1;
+	    }
+	  if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER)
+	    {
+		rowid_value = sqlite3_value_int64 (argv[3]);
+		ok_rowid = 1;
+	    }
+	  if (ok_prefix && ok_table && ok_geom && ok_rowid)
+	      ;
+	  else
+	    {
+		/* invalid args */
+		goto stop;
+	    }
+      }
+    if (idxNum == 4 && argc == 3)
+      {
+	  /* retrieving the DbPrefix/Table/ROWID params */
+	  if (sqlite3_value_type (argv[0]) == SQLITE_TEXT)
+	    {
+		db_prefix = (char *) sqlite3_value_text (argv[0]);
+		ok_prefix = 1;
+	    }
+	  if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
+	    {
+		table_name = (char *) sqlite3_value_text (argv[1]);
+		ok_table = 1;
+	    }
+	  if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
+	    {
+		rowid_value = sqlite3_value_int64 (argv[2]);
+		ok_rowid = 1;
+	    }
+	  if (ok_prefix && ok_table && ok_rowid)
+	      ;
+	  else
+	    {
+		/* invalid args */
+		goto stop;
+	    }
+      }
+
+/* checking if the corresponding Table/Geometry exists */
+    exists =
+	velem_find_geometry (elem->db, db_prefix, table_name, geom_column,
+			     &xprefix, &xtable, &xgeom);
+    if (!exists)
+	goto stop;
+
+/* building the basic query */
+    table_nameQ = gaiaDoubleQuotedSql (xtable);
+    geo_nameQ = gaiaDoubleQuotedSql (xgeom);
+    if (db_prefix == NULL)
+      {
+	  sql_statement =
+	      sqlite3_mprintf ("SELECT \"%s\" FROM \"%s\" WHERE ROWID = ?",
+			       geo_nameQ, table_nameQ);
+      }
+    else
+      {
+	  char *quoted_db = gaiaDoubleQuotedSql (db_prefix);
+	  sql_statement =
+	      sqlite3_mprintf
+	      ("SELECT \"%s\" FROM \"%s\".\"%s\" WHERE ROWID = ?", geo_nameQ,
+	       quoted_db, table_nameQ);
+	  free (quoted_db);
+      }
+    free (geo_nameQ);
+    free (table_nameQ);
+    ret =
+	sqlite3_prepare_v2 (elem->db, sql_statement, strlen (sql_statement),
+			    &stmt, NULL);
+    sqlite3_free (sql_statement);
+    if (ret != SQLITE_OK)
+	goto stop;
+/* binding stmt params [ROWID] */
+    sqlite3_bind_double (stmt, 1, rowid_value);
+    velem_reset_cache (cursor);
+    cursor->eof = 0;
+/* caching the ResultSet */
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_ROW)
+      {
+	  /* ok, found a corresponding row */
+	  cursor->db_prefix = xprefix;
+	  xprefix = NULL;
+	  cursor->f_table_name = xtable;
+	  xtable = NULL;
+	  cursor->f_geometry_column = xgeom;
+	  xgeom = NULL;
+	  cursor->origin_rowid = rowid_value;
+	  cursor->current = 0;
+	  if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+	    {
+		/* preparing Elementary Geometries */
+		gaiaGeomCollPtr geom;
+		unsigned char *blob =
+		    (unsigned char *) sqlite3_column_blob (stmt, 0);
+		int blob_sz = sqlite3_column_bytes (stmt, 0);
+		geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
+		if (geom == NULL)
+		    cursor->eof = 1;
+		else
+		  {
+		      int count = 0;
+		      gaiaPointPtr pt;
+		      gaiaLinestringPtr ln;
+		      gaiaPolygonPtr pg;
+		      pt = geom->FirstPoint;
+		      while (pt)
+			{
+			    count++;
+			    pt = pt->Next;
+			}
+		      ln = geom->FirstLinestring;
+		      while (ln)
+			{
+			    count++;
+			    ln = ln->Next;
+			}
+		      pg = geom->FirstPolygon;
+		      while (pg)
+			{
+			    count++;
+			    pg = pg->Next;
+			}
+		      cursor->count = count;
+		      cursor->geometries =
+			  malloc (sizeof (gaiaGeomCollPtr) * count);
+		      for (count = 0; count < cursor->count; count++)
+			  *(cursor->geometries + count) = NULL;
+		      count = 0;
+		      pt = geom->FirstPoint;
+		      while (pt)
+			{
+			    gaiaGeomCollPtr elem =
+				velem_from_point (pt, geom->Srid);
+			    *(cursor->geometries + count++) = elem;
+			    pt = pt->Next;
+			}
+		      ln = geom->FirstLinestring;
+		      while (ln)
+			{
+			    gaiaGeomCollPtr elem =
+				velem_from_linestring (ln, geom->Srid);
+			    *(cursor->geometries + count++) = elem;
+			    ln = ln->Next;
+			}
+		      pg = geom->FirstPolygon;
+		      while (pg)
+			{
+			    gaiaGeomCollPtr elem =
+				velem_from_polygon (pg, geom->Srid);
+			    *(cursor->geometries + count++) = elem;
+			    pg = pg->Next;
+			}
+		      gaiaFreeGeomColl (geom);
+		  }
+	    }
+      }
+    else
+	cursor->eof = 1;
+  stop:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (xtable)
+	free (xtable);
+    if (xgeom)
+	free (xgeom);
+    if (xprefix)
+	free (xprefix);
+    if (cursor->eof == 1)
+	velem_reset_cache (cursor);
+    return SQLITE_OK;
+}
+
+static int
+velem_next (sqlite3_vtab_cursor * pCursor)
+{
+/* fetching next row from cursor */
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    if (cursor->geometries == NULL)
+	cursor->eof = 1;
+    else
+      {
+	  cursor->current += 1;
+	  if (cursor->current >= cursor->count)
+	      cursor->eof = 1;
+      }
+    return SQLITE_OK;
+}
+
+static int
+velem_eof (sqlite3_vtab_cursor * pCursor)
+{
+/* cursor EOF */
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    return cursor->eof;
+}
+
+static int
+velem_column (sqlite3_vtab_cursor * pCursor, sqlite3_context * pContext,
+	      int column)
+{
+/* fetching value for the Nth column */
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    if (column == 0)
+      {
+	  /* the "db_prefix" column */
+	  if (cursor->db_prefix == NULL)
+	      sqlite3_result_null (pContext);
+	  else
+	      sqlite3_result_text (pContext, cursor->db_prefix,
+				   strlen (cursor->db_prefix), SQLITE_STATIC);
+      }
+    if (column == 1)
+      {
+	  /* the "f_table_name" column */
+	  if (cursor->f_table_name == NULL)
+	      sqlite3_result_null (pContext);
+	  else
+	      sqlite3_result_text (pContext, cursor->f_table_name,
+				   strlen (cursor->f_table_name),
+				   SQLITE_STATIC);
+      }
+    if (column == 2)
+      {
+	  /* the "f_geometry_column" column */
+	  if (cursor->f_geometry_column == NULL)
+	      sqlite3_result_null (pContext);
+	  else
+	      sqlite3_result_text (pContext, cursor->f_geometry_column,
+				   strlen (cursor->f_geometry_column),
+				   SQLITE_STATIC);
+      }
+    if (column == 3)
+      {
+	  /* the "origin_rowid" column */
+	  sqlite3_result_int64 (pContext, cursor->origin_rowid);
+      }
+    if (column == 4)
+      {
+	  /* the "item_no" column */
+	  sqlite3_result_int (pContext, cursor->current);
+      }
+    if (column == 5)
+      {
+	  /* the "geometry" column */
+	  gaiaGeomCollPtr geom = *(cursor->geometries + cursor->current);
+	  if (geom == NULL)
+	      sqlite3_result_null (pContext);
+	  else
+	    {
+		unsigned char *blob;
+		int size;
+		gaiaToSpatiaLiteBlobWkb (geom, &blob, &size);
+		sqlite3_result_blob (pContext, blob, size, free);
+	    }
+      }
+    return SQLITE_OK;
+}
+
+static int
+velem_rowid (sqlite3_vtab_cursor * pCursor, sqlite_int64 * pRowid)
+{
+/* fetching the ROWID */
+    VirtualElementaryCursorPtr cursor = (VirtualElementaryCursorPtr) pCursor;
+    *pRowid = cursor->current;
+    return SQLITE_OK;
+}
+
+static int
+velem_update (sqlite3_vtab * pVTab, int argc, sqlite3_value ** argv,
+	      sqlite_int64 * pRowid)
+{
+/* generic update [INSERT / UPDATE / DELETE */
+    if (pRowid || argc || argv || pVTab)
+	pRowid = pRowid;	/* unused arg warning suppression */
+/* read only datasource */
+    return SQLITE_READONLY;
+}
+
+static int
+velem_begin (sqlite3_vtab * pVTab)
+{
+/* BEGIN TRANSACTION */
+    if (pVTab)
+	pVTab = pVTab;		/* unused arg warning suppression */
+    return SQLITE_OK;
+}
+
+static int
+velem_sync (sqlite3_vtab * pVTab)
+{
+/* BEGIN TRANSACTION */
+    if (pVTab)
+	pVTab = pVTab;		/* unused arg warning suppression */
+    return SQLITE_OK;
+}
+
+static int
+velem_commit (sqlite3_vtab * pVTab)
+{
+/* BEGIN TRANSACTION */
+    if (pVTab)
+	pVTab = pVTab;		/* unused arg warning suppression */
+    return SQLITE_OK;
+}
+
+static int
+velem_rollback (sqlite3_vtab * pVTab)
+{
+/* BEGIN TRANSACTION */
+    if (pVTab)
+	pVTab = pVTab;		/* unused arg warning suppression */
+    return SQLITE_OK;
+}
+
+static int
+spliteVirtualElementaryInit (sqlite3 * db)
+{
+    int rc = SQLITE_OK;
+    my_elem_module.iVersion = 1;
+    my_elem_module.xCreate = &velem_create;
+    my_elem_module.xConnect = &velem_connect;
+    my_elem_module.xBestIndex = &velem_best_index;
+    my_elem_module.xDisconnect = &velem_disconnect;
+    my_elem_module.xDestroy = &velem_destroy;
+    my_elem_module.xOpen = &velem_open;
+    my_elem_module.xClose = &velem_close;
+    my_elem_module.xFilter = &velem_filter;
+    my_elem_module.xNext = &velem_next;
+    my_elem_module.xEof = &velem_eof;
+    my_elem_module.xColumn = &velem_column;
+    my_elem_module.xRowid = &velem_rowid;
+    my_elem_module.xUpdate = &velem_update;
+    my_elem_module.xBegin = &velem_begin;
+    my_elem_module.xSync = &velem_sync;
+    my_elem_module.xCommit = &velem_commit;
+    my_elem_module.xRollback = &velem_rollback;
+    my_elem_module.xFindFunction = NULL;
+    sqlite3_create_module_v2 (db, "VirtualElementary", &my_elem_module, NULL,
+			      0);
+    return rc;
+}
+
+SPATIALITE_PRIVATE int
+virtual_elementary_extension_init (void *xdb)
+{
+    sqlite3 *db = (sqlite3 *) xdb;
+    return spliteVirtualElementaryInit (db);
+}
diff --git a/src/spatialite/virtualfdo.c b/src/spatialite/virtualfdo.c
index d08d335..cdc8abc 100644
--- a/src/spatialite/virtualfdo.c
+++ b/src/spatialite/virtualfdo.c
@@ -1115,7 +1115,7 @@ vfdo_update_row (VirtualFDOPtr p_vt, sqlite3_int64 rowid, int argc,
     char *sql;
     char buf[256];
     char *xname;
-    gaiaGeomCollPtr geom;
+    gaiaGeomCollPtr geom = NULL;
     gaiaOutBufferInitialize (&sql_statement);
     xname = gaiaDoubleQuotedSql (p_vt->table);
     sql = sqlite3_mprintf ("UPDATE \"%s\" SET", xname);
diff --git a/src/spatialite/virtualshape.c b/src/spatialite/virtualshape.c
index 04fd607..e7be7c3 100644
--- a/src/spatialite/virtualshape.c
+++ b/src/spatialite/virtualshape.c
@@ -79,6 +79,7 @@ typedef struct VirtualShapeStruct
     sqlite3 *db;		/* the sqlite db holding the virtual table */
     gaiaShapefilePtr Shp;	/* the Shapefile struct */
     int Srid;			/* the Shapefile SRID */
+    int text_dates;
 } VirtualShape;
 typedef VirtualShape *VirtualShapePtr;
 
@@ -180,6 +181,7 @@ vshp_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
     int seed;
     int dup;
     int idup;
+    int text_dates = 0;
     char *xname;
     char **col_name = NULL;
     int geotype;
@@ -187,7 +189,7 @@ vshp_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
     if (pAux)
 	pAux = pAux;		/* unused arg warning suppression */
 /* checking for shapefile PATH */
-    if (argc == 6)
+    if (argc == 6 || argc == 7)
       {
 	  pPath = argv[3];
 	  len = strlen (pPath);
@@ -217,6 +219,8 @@ vshp_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
 	  srid = atoi (argv[5]);
 	  if (srid < 0)
 	      srid = -1;
+	  if (argc == 7)
+	      text_dates = atoi (argv[6]);
       }
     else
       {
@@ -234,6 +238,7 @@ vshp_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
     p_vt->db = db;
     p_vt->Shp = gaiaAllocShapefile ();
     p_vt->Srid = srid;
+    p_vt->text_dates = text_dates;
 /* trying to open files etc in order to ensure we actually have a genuine shapefile */
     gaiaOpenShpRead (p_vt->Shp, path, encoding, "UTF-8");
     if (!(p_vt->Shp->Valid))
@@ -314,6 +319,15 @@ vshp_create (sqlite3 * db, void *pAux, int argc, const char *const *argv,
 	    }
 	  else if (pFld->Type == 'F')
 	      sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname);
+	  else if (pFld->Type == 'D')
+	    {
+		if (text_dates)
+		    sql =
+			sqlite3_mprintf (", \"%s\" VARCHAR(%d)", xname,
+					 pFld->Length);
+		else
+		    sql = sqlite3_mprintf (", \"%s\" DOUBLE", xname);
+	    }
 	  else
 	      sql =
 		  sqlite3_mprintf (", \"%s\" VARCHAR(%d)", xname, pFld->Length);
@@ -622,8 +636,8 @@ vshp_read_row (VirtualShapeCursorPtr cursor)
 	  cursor->blobGeometry = NULL;
       }
     ret =
-	gaiaReadShpEntity (cursor->pVtab->Shp, cursor->current_row,
-			   cursor->pVtab->Srid);
+	gaiaReadShpEntity_ex (cursor->pVtab->Shp, cursor->current_row,
+			      cursor->pVtab->Srid, cursor->pVtab->text_dates);
     if (!ret)
       {
 	  if (!(cursor->pVtab->Shp->LastError))	/* normal SHP EOF */
diff --git a/test/Makefile.am b/test/Makefile.am
index f4bece8..f36c997 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -22,6 +22,7 @@ check_PROGRAMS = check_endian \
 		shape_utf8_1ex \
 		shape_utf8_2 \
 		shape_3d \
+		check_clone_table \
 		check_xls_load \
 		check_math_funcs \
 		check_gaia_util \
@@ -50,7 +51,8 @@ check_PROGRAMS = check_endian \
 		check_virtualbbox \
 		check_wfsin \
 		check_dxf \
-		check_metacatalog
+		check_metacatalog \
+		check_virtualelem
 		
 if ENABLE_GEOPACKAGE
 check_PROGRAMS += \
@@ -179,4 +181,5 @@ SUBDIRS = sql_stmt_geosadvanced_tests sql_stmt_geos_tests \
 	sql_stmt_libxml2_tests sql_stmt_lwgeom_tests \
 	sql_stmt_mathsql_tests sql_stmt_proj_tests \
 	sql_stmt_security_tests sql_stmt_tests \
-	sql_stmt_xmlsec_tests sql_stmt_geopackage_tests
+	sql_stmt_xmlsec_tests sql_stmt_geopackage_tests \
+	sql_stmt_freexl_tests
diff --git a/test/Makefile.in b/test/Makefile.in
index 818a4ec..3858d94 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -87,22 +87,23 @@ check_PROGRAMS = check_endian$(EXEEXT) check_version$(EXEEXT) \
 	check_shp_load_3d$(EXEEXT) shape_cp1252$(EXEEXT) \
 	shape_primitives$(EXEEXT) shape_utf8_1$(EXEEXT) \
 	shape_utf8_1ex$(EXEEXT) shape_utf8_2$(EXEEXT) \
-	shape_3d$(EXEEXT) check_xls_load$(EXEEXT) \
-	check_math_funcs$(EXEEXT) check_gaia_util$(EXEEXT) \
-	check_gaia_utf8$(EXEEXT) check_extension$(EXEEXT) \
-	check_recover_geom$(EXEEXT) check_sql_stmt$(EXEEXT) \
-	check_multithread$(EXEEXT) check_virtualtable1$(EXEEXT) \
-	check_virtualtable2$(EXEEXT) check_virtualtable3$(EXEEXT) \
-	check_virtualtable4$(EXEEXT) check_virtualtable5$(EXEEXT) \
-	check_virtualtable6$(EXEEXT) check_virtual_ovflw$(EXEEXT) \
-	check_mbrcache$(EXEEXT) check_spatialindex$(EXEEXT) \
-	check_exif$(EXEEXT) check_exif2$(EXEEXT) \
-	check_relations_fncts$(EXEEXT) \
+	shape_3d$(EXEEXT) check_clone_table$(EXEEXT) \
+	check_xls_load$(EXEEXT) check_math_funcs$(EXEEXT) \
+	check_gaia_util$(EXEEXT) check_gaia_utf8$(EXEEXT) \
+	check_extension$(EXEEXT) check_recover_geom$(EXEEXT) \
+	check_sql_stmt$(EXEEXT) check_multithread$(EXEEXT) \
+	check_virtualtable1$(EXEEXT) check_virtualtable2$(EXEEXT) \
+	check_virtualtable3$(EXEEXT) check_virtualtable4$(EXEEXT) \
+	check_virtualtable5$(EXEEXT) check_virtualtable6$(EXEEXT) \
+	check_virtual_ovflw$(EXEEXT) check_mbrcache$(EXEEXT) \
+	check_spatialindex$(EXEEXT) check_exif$(EXEEXT) \
+	check_exif2$(EXEEXT) check_relations_fncts$(EXEEXT) \
 	check_extra_relations_fncts$(EXEEXT) \
 	check_geoscvt_fncts$(EXEEXT) check_libxml2$(EXEEXT) \
 	check_styling$(EXEEXT) check_virtualxpath$(EXEEXT) \
 	check_virtualbbox$(EXEEXT) check_wfsin$(EXEEXT) \
-	check_dxf$(EXEEXT) check_metacatalog$(EXEEXT) $(am__EXEEXT_1)
+	check_dxf$(EXEEXT) check_metacatalog$(EXEEXT) \
+	check_virtualelem$(EXEEXT) $(am__EXEEXT_1)
 @ENABLE_GEOPACKAGE_TRUE at am__append_1 = \
 @ENABLE_GEOPACKAGE_TRUE@		check_createBaseTables \
 @ENABLE_GEOPACKAGE_TRUE@		check_gpkgCreateTilesTable \
@@ -191,6 +192,9 @@ check_add_tile_triggers_bad_table_name_LDADD = $(LDADD)
 check_bufovflw_SOURCES = check_bufovflw.c
 check_bufovflw_OBJECTS = check_bufovflw.$(OBJEXT)
 check_bufovflw_LDADD = $(LDADD)
+check_clone_table_SOURCES = check_clone_table.c
+check_clone_table_OBJECTS = check_clone_table.$(OBJEXT)
+check_clone_table_LDADD = $(LDADD)
 check_create_SOURCES = check_create.c
 check_create_OBJECTS = check_create.$(OBJEXT)
 check_create_LDADD = $(LDADD)
@@ -409,6 +413,9 @@ check_virtual_ovflw_LDADD = $(LDADD)
 check_virtualbbox_SOURCES = check_virtualbbox.c
 check_virtualbbox_OBJECTS = check_virtualbbox.$(OBJEXT)
 check_virtualbbox_LDADD = $(LDADD)
+check_virtualelem_SOURCES = check_virtualelem.c
+check_virtualelem_OBJECTS = check_virtualelem.$(OBJEXT)
+check_virtualelem_LDADD = $(LDADD)
 check_virtualtable1_SOURCES = check_virtualtable1.c
 check_virtualtable1_OBJECTS = check_virtualtable1.$(OBJEXT)
 check_virtualtable1_LDADD = $(LDADD)
@@ -490,10 +497,10 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = check_add_tile_triggers.c \
 	check_add_tile_triggers_bad_table_name.c check_bufovflw.c \
-	check_create.c check_createBaseTables.c check_dbf_load.c \
-	check_dxf.c check_endian.c check_exif.c check_exif2.c \
-	check_extension.c check_extra_relations_fncts.c check_fdo1.c \
-	check_fdo2.c check_fdo3.c check_fdo_bufovflw.c \
+	check_clone_table.c check_create.c check_createBaseTables.c \
+	check_dbf_load.c check_dxf.c check_endian.c check_exif.c \
+	check_exif2.c check_extension.c check_extra_relations_fncts.c \
+	check_fdo1.c check_fdo2.c check_fdo3.c check_fdo_bufovflw.c \
 	check_gaia_utf8.c check_gaia_util.c check_geom_aux.c \
 	check_geometry_cols.c check_geoscvt_fncts.c \
 	check_get_normal_row.c check_get_normal_row_bad_geopackage.c \
@@ -520,18 +527,18 @@ SOURCES = check_add_tile_triggers.c \
 	check_relations_fncts.c check_shp_load.c check_shp_load_3d.c \
 	check_spatialindex.c check_sql_stmt.c check_styling.c \
 	check_version.c check_virtual_ovflw.c check_virtualbbox.c \
-	check_virtualtable1.c check_virtualtable2.c \
-	check_virtualtable3.c check_virtualtable4.c \
-	check_virtualtable5.c check_virtualtable6.c \
-	check_virtualxpath.c check_wfsin.c check_xls_load.c shape_3d.c \
-	shape_cp1252.c shape_primitives.c shape_utf8_1.c \
-	shape_utf8_1ex.c shape_utf8_2.c
+	check_virtualelem.c check_virtualtable1.c \
+	check_virtualtable2.c check_virtualtable3.c \
+	check_virtualtable4.c check_virtualtable5.c \
+	check_virtualtable6.c check_virtualxpath.c check_wfsin.c \
+	check_xls_load.c shape_3d.c shape_cp1252.c shape_primitives.c \
+	shape_utf8_1.c shape_utf8_1ex.c shape_utf8_2.c
 DIST_SOURCES = check_add_tile_triggers.c \
 	check_add_tile_triggers_bad_table_name.c check_bufovflw.c \
-	check_create.c check_createBaseTables.c check_dbf_load.c \
-	check_dxf.c check_endian.c check_exif.c check_exif2.c \
-	check_extension.c check_extra_relations_fncts.c check_fdo1.c \
-	check_fdo2.c check_fdo3.c check_fdo_bufovflw.c \
+	check_clone_table.c check_create.c check_createBaseTables.c \
+	check_dbf_load.c check_dxf.c check_endian.c check_exif.c \
+	check_exif2.c check_extension.c check_extra_relations_fncts.c \
+	check_fdo1.c check_fdo2.c check_fdo3.c check_fdo_bufovflw.c \
 	check_gaia_utf8.c check_gaia_util.c check_geom_aux.c \
 	check_geometry_cols.c check_geoscvt_fncts.c \
 	check_get_normal_row.c check_get_normal_row_bad_geopackage.c \
@@ -558,12 +565,12 @@ DIST_SOURCES = check_add_tile_triggers.c \
 	check_relations_fncts.c check_shp_load.c check_shp_load_3d.c \
 	check_spatialindex.c check_sql_stmt.c check_styling.c \
 	check_version.c check_virtual_ovflw.c check_virtualbbox.c \
-	check_virtualtable1.c check_virtualtable2.c \
-	check_virtualtable3.c check_virtualtable4.c \
-	check_virtualtable5.c check_virtualtable6.c \
-	check_virtualxpath.c check_wfsin.c check_xls_load.c shape_3d.c \
-	shape_cp1252.c shape_primitives.c shape_utf8_1.c \
-	shape_utf8_1ex.c shape_utf8_2.c
+	check_virtualelem.c check_virtualtable1.c \
+	check_virtualtable2.c check_virtualtable3.c \
+	check_virtualtable4.c check_virtualtable5.c \
+	check_virtualtable6.c check_virtualxpath.c check_wfsin.c \
+	check_xls_load.c shape_3d.c shape_cp1252.c shape_primitives.c \
+	shape_utf8_1.c shape_utf8_1ex.c shape_utf8_2.c
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
 	install-data-recursive install-dvi-recursive \
@@ -1056,7 +1063,8 @@ SUBDIRS = sql_stmt_geosadvanced_tests sql_stmt_geos_tests \
 	sql_stmt_libxml2_tests sql_stmt_lwgeom_tests \
 	sql_stmt_mathsql_tests sql_stmt_proj_tests \
 	sql_stmt_security_tests sql_stmt_tests \
-	sql_stmt_xmlsec_tests sql_stmt_geopackage_tests
+	sql_stmt_xmlsec_tests sql_stmt_geopackage_tests \
+	sql_stmt_freexl_tests
 
 all: all-recursive
 
@@ -1114,6 +1122,10 @@ check_bufovflw$(EXEEXT): $(check_bufovflw_OBJECTS) $(check_bufovflw_DEPENDENCIES
 	@rm -f check_bufovflw$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(check_bufovflw_OBJECTS) $(check_bufovflw_LDADD) $(LIBS)
 
+check_clone_table$(EXEEXT): $(check_clone_table_OBJECTS) $(check_clone_table_DEPENDENCIES) $(EXTRA_check_clone_table_DEPENDENCIES) 
+	@rm -f check_clone_table$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(check_clone_table_OBJECTS) $(check_clone_table_LDADD) $(LIBS)
+
 check_create$(EXEEXT): $(check_create_OBJECTS) $(check_create_DEPENDENCIES) $(EXTRA_check_create_DEPENDENCIES) 
 	@rm -f check_create$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(check_create_OBJECTS) $(check_create_LDADD) $(LIBS)
@@ -1358,6 +1370,10 @@ check_virtualbbox$(EXEEXT): $(check_virtualbbox_OBJECTS) $(check_virtualbbox_DEP
 	@rm -f check_virtualbbox$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(check_virtualbbox_OBJECTS) $(check_virtualbbox_LDADD) $(LIBS)
 
+check_virtualelem$(EXEEXT): $(check_virtualelem_OBJECTS) $(check_virtualelem_DEPENDENCIES) $(EXTRA_check_virtualelem_DEPENDENCIES) 
+	@rm -f check_virtualelem$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(check_virtualelem_OBJECTS) $(check_virtualelem_LDADD) $(LIBS)
+
 check_virtualtable1$(EXEEXT): $(check_virtualtable1_OBJECTS) $(check_virtualtable1_DEPENDENCIES) $(EXTRA_check_virtualtable1_DEPENDENCIES) 
 	@rm -f check_virtualtable1$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(check_virtualtable1_OBJECTS) $(check_virtualtable1_LDADD) $(LIBS)
@@ -1427,6 +1443,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_add_tile_triggers.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_add_tile_triggers_bad_table_name.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_bufovflw.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_clone_table.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_create.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_createBaseTables.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_dbf_load.Po at am__quote@
@@ -1488,6 +1505,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_version.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtual_ovflw.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtualbbox.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtualelem.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtualtable1.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtualtable2.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/check_virtualtable3.Po at am__quote@
@@ -1925,6 +1943,13 @@ shape_3d.log: shape_3d$(EXEEXT)
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+check_clone_table.log: check_clone_table$(EXEEXT)
+	@p='check_clone_table$(EXEEXT)'; \
+	b='check_clone_table'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 check_xls_load.log: check_xls_load$(EXEEXT)
 	@p='check_xls_load$(EXEEXT)'; \
 	b='check_xls_load'; \
@@ -2128,6 +2153,13 @@ check_metacatalog.log: check_metacatalog$(EXEEXT)
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+check_virtualelem.log: check_virtualelem$(EXEEXT)
+	@p='check_virtualelem$(EXEEXT)'; \
+	b='check_virtualelem'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 check_createBaseTables.log: check_createBaseTables$(EXEEXT)
 	@p='check_createBaseTables$(EXEEXT)'; \
 	b='check_createBaseTables'; \
diff --git a/test/check_bufovflw.c b/test/check_bufovflw.c
index 9f519e6..95ca672 100644
--- a/test/check_bufovflw.c
+++ b/test/check_bufovflw.c
@@ -1202,7 +1202,8 @@ main (int argc, char *argv[])
 			 "POLYGONZ((0 0 0, %1.0f 0 0, %1.0f %1.0f %1.0f, 0 %1.0f 0, 0 0 0), "
 			 "(5 5 0, %1.0f 5 0, %1.0f %1.0f %1.0f, 5 %1.0f 0, 5 5 0)))'))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
+			 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1256,7 +1257,8 @@ main (int argc, char *argv[])
 			 "POLYGONM((0 0 0, %1.0f 0 0, %1.0f %1.0f %1.0f, 0 %1.0f 0, 0 0 0), "
 			 "(5 5 0, %1.0f 5 0, %1.0f %1.0f %1.0f, 5 %1.0f 0, 5 5 0)))'))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
+			 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1310,8 +1312,8 @@ main (int argc, char *argv[])
 			 "POLYGONZM((0 0 0 0, %1.0f 0 0 0, %1.0f %1.0f %1.0f %1.0f, 0 %1.0f 0 0, 0 0 0 0), "
 			 "(5 5 0 0, %1.0f 5 0 0, %1.0f %1.0f %1.0f %1.0f, 5 %1.0f 0 0, 5 5 0 0)))'))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128);
+			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
+			 1e128, 1e128, 1e128, 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1411,14 +1413,15 @@ main (int argc, char *argv[])
 	 "POLYGON((0 0 0,%1.0f 0 0,%1.0f %1.0f %1.0f,0 %1.0f 0,0 0 0),"
 	 "(5 5 0,%1.0f 5 0,%1.0f %1.0f %1.0f,5 %1.0f 0,5 5 0)))", 1e128, 1e128,
 	 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-	 1e128, 1e128);
+	 1e128, 1e128, 1e128, 1e128);
     sql =
 	sqlite3_mprintf ("SELECT AsEWKT(GeomFromText('GEOMETRYCOLLECTIONZ("
 			 "POINTZ(%1.0f %1.0f %1.0f), LINESTRINGZ(0 0 0, %1.0f %1.0f %1.0f), "
 			 "POLYGONZ((0 0 0, %1.0f 0 0, %1.0f %1.0f %1.0f, 0 %1.0f 0, 0 0 0), "
 			 "(5 5 0, %1.0f 5 0, %1.0f %1.0f %1.0f, 5 %1.0f 0, 5 5 0)))', 4326))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
+			 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1465,14 +1468,15 @@ main (int argc, char *argv[])
 	 "POLYGONM((0 0 0,%1.0f 0 0,%1.0f %1.0f %1.0f,0 %1.0f 0,0 0 0),"
 	 "(5 5 0,%1.0f 5 0,%1.0f %1.0f %1.0f,5 %1.0f 0,5 5 0)))", 1e128, 1e128,
 	 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-	 1e128, 1e128);
+	 1e128, 1e128, 1e128, 1e128);
     sql =
 	sqlite3_mprintf ("SELECT AsEWKT(GeomFromText('GEOMETRYCOLLECTIONM("
 			 "POINTM(%1.0f %1.0f %1.0f), LINESTRINGM(0 0 0, %1.0f %1.0f %1.0f), "
 			 "POLYGONM((0 0 0, %1.0f 0 0, %1.0f %1.0f %1.0f, 0 %1.0f 0, 0 0 0), "
 			 "(5 5 0, %1.0f 5 0, %1.0f %1.0f %1.0f, 5 %1.0f 0, 5 5 0)))', 4326))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
+			 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1519,7 +1523,7 @@ main (int argc, char *argv[])
 	 "POLYGON((0 0 0 0,%1.0f 0 0 0,%1.0f %1.0f %1.0f %1.0f,0 %1.0f 0 0,0 0 0 0),"
 	 "(5 5 0 0,%1.0f 5 0 0,%1.0f %1.0f %1.0f %1.0f,5 %1.0f 0 0,5 5 0 0)))",
 	 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-	 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
+	 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128);
     sql =
 	sqlite3_mprintf ("SELECT AsEWKT(GeomFromText('GEOMETRYCOLLECTIONZM("
 			 "POINTZM(%1.0f %1.0f %1.0f %1.0f), LINESTRINGZM(0 0 0 0, %1.0f %1.0f %1.0f %1.0f), "
@@ -1527,7 +1531,7 @@ main (int argc, char *argv[])
 			 "(5 5 0 0, %1.0f 5 0 0, %1.0f %1.0f %1.0f %1.0f, 5 %1.0f 0 0, 5 5 0 0)))', 4326))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1581,7 +1585,7 @@ main (int argc, char *argv[])
 			 "(5 5 0 0, %1.0f 5 0 0, %1.0f %1.0f %1.0f %1.0f, 5 %1.0f 0 0, 5 5 0 0)))', 4326))",
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
 			 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128, 1e128,
-			 1e128, 1e128);
+			 1e128, 1e128, 1e128, 1e128);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
diff --git a/test/check_clone_table.c b/test/check_clone_table.c
new file mode 100644
index 0000000..cce924a
--- /dev/null
+++ b/test/check_clone_table.c
@@ -0,0 +1,1442 @@
+/*
+
+ check_clone_table.c -- SpatiaLite Test Case
+ 
+ This tests a couple of functions in gg_relations.c that aren't used in
+ spatialite, but are provided for backwards compatibility.
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the SpatiaLite library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2011
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+  
+*/
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+#include "spatialite/gaiageo.h"
+
+int
+execute_check (sqlite3 * sqlite, const char *sql, char **error)
+{
+/* executing an SQL statement returning True/False */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = 0;
+
+    *error = NULL;
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  *error = sqlite3_mprintf ("%s", sqlite3_errmsg (sqlite));
+	  return SQLITE_ERROR;
+      }
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    if (retcode == 1)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+int
+create_origin ()
+{
+/* creating the origin DB */
+    int ret;
+    sqlite3 *handle;
+    char *err_msg = NULL;
+    const char *sql;
+    void *cache = spatialite_alloc_connection ();
+
+    ret =
+	sqlite3_open_v2 ("clone_origin.sqlite", &handle,
+			 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "cannot open clone_origin database: %s\n",
+		   sqlite3_errmsg (handle));
+	  sqlite3_close (handle);
+	  return -1;
+      }
+
+    spatialite_init_ex (handle, cache, 0);
+
+    ret =
+	sqlite3_exec (handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  sqlite3_close (handle);
+	  return -2;
+      }
+
+/* creating the input table #1 */
+    sql = "CREATE TABLE input_1 (id INTEGER NOT NULL PRIMARY KEY,"
+	"name TEXT NOT NULL, measure DOUBLE NOT NULL)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -3;
+      }
+/* populating the input table #1 */
+    sql = "INSERT INTO input_1 (id, name, measure) VALUES "
+	"(1, 'alpha', 1.51), (2, 'beta', 2.34), (3, 'gamma', 3.75), "
+	"(4, 'delta', 4.81), (5, 'epsilon', 5.03)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -4;
+      }
+
+/* creating the input table #2 */
+    sql = "CREATE TABLE input_2 (first_name TEXT, last_name TEXT, "
+	"birthday TEXT, address TEXT, town TEXT DEFAULT 'Arezzo', "
+	"code_2 TEXT, code_1 TEXT, number INT, code_3 TEXT, "
+	"CONSTRAINT pk_2 PRIMARY KEY (code_1, code_2, code_3))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -5;
+      }
+/* populating the input table #2 */
+    sql = "INSERT INTO input_2 (first_name, last_name, birthday, "
+	" address, town, code_2, code_1, number, code_3) VALUES "
+	"('Peter', 'Smith', '1935-05-28', 'Oak Road', 'London', 'uk', 'bb', 1, 'cc'), "
+	"('Paul', 'Dupont', '1981-02-13', 'Rue Blanche', 'Paris', 'fr', 'kk', 2, 'zz'), "
+	"('Daniel', 'Khun', '1967-11-12', 'Berner Strasse', 'Berlin', 'de', 'mm', 3, 'nn')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -6;
+      }
+    sql = "INSERT INTO input_2 (first_name, last_name, address, "
+	" code_2, code_1, number, code_3) VALUES "
+	"('Mario', 'Rossi', NULL, 'it', 'aa', 1, '01'), "
+	"('Lucia', 'Bianchi', NULL, 'it', 'aa', 1, '02'), "
+	"('Tina', 'Gialli', 'Via Roma', 'it', 'ab', 1, '01'), "
+	"('Paolo', 'Verdi', NULL, 'it', 'ab', 2, '02')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -7;
+      }
+
+/* creating the input table #3 */
+    sql = "CREATE TABLE input_3 (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -8;
+      }
+    sql = "SELECT AddGeometryColumn('input_3', 'geom', 4326, 'POLYGON', 'XY')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -9;
+      }
+    sql = "SELECT CreateSpatialIndex('input_3', 'geom')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -10;
+      }
+/* populating the input table #3 */
+    sql = "INSERT INTO input_3 (id, name, geom) VALUES "
+	"(NULL, 'one', BuildMbr(0, 0, 1, 1, 4326)), "
+	"(NULL, 'two', BuildMbr(1, 1, 2, 2, 4326)), "
+	"(NULL, 'three', BuildMbr(2, 2, 3, 3, 4326)), "
+	"(NULL, 'four', BuildMbr(3, 3, 4, 4, 4326)), "
+	"(NULL, 'five', BuildMbr(4, 4, 5, 5, 4326)), "
+	"(1000, 'six', BuildMbr(5, 5, 6, 6, 4326)), "
+	"(NULL, 'seven', BuildMbr(6, 6, 7, 7, 4326)), "
+	"(NULL, 'height', BuildMbr(7, 7, 8, 8, 4326)), "
+	"(NULL, 'nine', BuildMbr(8, 8, 9, 9, 4326)), "
+	"(NULL, 'ten', BuildMbr(9, 9, 10, 10, 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -11;
+      }
+
+/* creating the input table #4 */
+    sql = "CREATE TABLE input_4 (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT, tbl_1 INTEGER, code_2 TEXT NOT NULL, "
+	"code_3 TEXT NOT NULL, code_1 TEXT NOT NULL, tbl_3 INTEGER, "
+	"ignore_1 TEXT DEFAULT 'foo', ignore_2 TEXT DEFAULT 'foo', "
+	"ignore_3 TEXT DEFAULT 'foo', ignore_4 TEXT DEFAULT 'foo', "
+	"ignore_5 TEXT DEFAULT 'foo', ignore_6 TEXT DEFAULT 'foo', "
+	"ignore_7 TEXT DEFAULT 'foo', ignore_8 TEXT DEFAULT 'foo', "
+	"ignore_9 TEXT DEFAULT 'foo', ignore_10 TEXT DEFAULT 'foo', "
+	"CONSTRAINT fk_tbl4_tbl1 FOREIGN KEY (tbl_1) REFERENCES input_1 (id), "
+	"CONSTRAINT fk_tbl4_tbl2 FOREIGN KEY (code_1, code_2, code_3) "
+	"REFERENCES input_2 (code_1, code_2, code_3) "
+	"ON UPDATE CASCADE ON DELETE CASCADE)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -12;
+      }
+    sql = "SELECT AddGeometryColumn('input_4', 'geom', 4326, 'POINT', 'XY')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -13;
+      }
+/* adding several Indices */
+    sql = "CREATE INDEX idx_4_tbl1 ON input_4 (tbl_1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -14;
+      }
+    sql = "CREATE INDEX idx_4_tbl2 ON input_4 (code_1, code_2, code_3)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -15;
+      }
+    sql = "CREATE UNIQUE INDEX idx_4_name ON input_4 (name)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -16;
+      }
+/* creating Triggers on input table #4 */
+    sql = "CREATE TRIGGER find_polygon_ins AFTER INSERT ON input_4 "
+	"BEGIN UPDATE input_4 SET tbl_3 = "
+	"(SELECT id FROM input_3 WHERE ST_Intersects(geom, NEW.geom) = 1) "
+	"WHERE id = NEW.id; END";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -17;
+      }
+    sql = "CREATE TRIGGER find_polygon_upd AFTER UPDATE OF geom ON input_4 "
+	"BEGIN UPDATE input_4 SET tbl_3 = "
+	"(SELECT id FROM input_3 WHERE ST_Intersects(geom, NEW.geom) = 1) "
+	"WHERE id = NEW.id; END";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -18;
+      }
+
+/* populating the input table #4 */
+    sql =
+	"INSERT INTO input_4 (id, name, tbl_1, code_2, code_3, code_1, geom) VALUES "
+	"(NULL, 'alpha', 1, 'it', '01', 'aa', MakePoint(0.5, 0.5, 4326)), "
+	"(NULL, 'beta', 1, 'fr', 'zz', 'kk', MakePoint(1.5, 1.5, 4326)), "
+	"(NULL, 'gamma', 2, 'uk', 'cc', 'bb', MakePoint(2.5, 2.5, 4326)), "
+	"(100, 'delta', 2, 'de', 'nn', 'mm', MakePoint(3.5, 3.5, 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -19;
+      }
+    sql =
+	"INSERT INTO input_4 (id, name, tbl_1, code_2, code_3, code_1, geom) VALUES "
+	"(NULL, 'epsilon', 3, 'it', '01', 'ab', MakePoint(4.5, 4.5, 4326)), "
+	"(200, 'zeta', 3, 'it', '01', 'ab', MakePoint(5.5, 5.5, 4326)), "
+	"(300, 'eta', 4, 'it', '02', 'aa', MakePoint(6.5, 6.5, 4326)), "
+	"(NULL, 'iota', 5, 'it', '02', 'ab', MakePoint(7.5, 7.5, 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -20;
+      }
+
+/* creating the input table Linestring XY */
+    sql = "CREATE TABLE ln_xy (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -21;
+      }
+    sql = "SELECT AddGeometryColumn('ln_xy', 'geom', 4326, 'LINESTRING', 'XY')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -22;
+      }
+/* populating the input table Linestring XY */
+    sql = "INSERT INTO ln_xy (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('LINESTRING(0 0, 1 1)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -23;
+      }
+
+/* creating the input table Linestring XYZ */
+    sql = "CREATE TABLE ln_xyz (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -24;
+      }
+    sql =
+	"SELECT AddGeometryColumn('ln_xyz', 'geom', 4326, 'LINESTRING', 'XYZ')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -25;
+      }
+/* populating the input table Linestring XYZ */
+    sql = "INSERT INTO ln_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('LINESTRINGZ(0 0 0, 1 1 1)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -26;
+      }
+
+/* creating the input table Linestring XYM */
+    sql = "CREATE TABLE ln_xym (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -27;
+      }
+    sql =
+	"SELECT AddGeometryColumn('ln_xym', 'geom', 4326, 'LINESTRING', 'XYM')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -28;
+      }
+/* populating the input table Linestring XYM */
+    sql = "INSERT INTO ln_xym (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('LINESTRINGM(0 0 0, 1 1 1)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -29;
+      }
+
+/* creating the input table Linestring XYZM */
+    sql = "CREATE TABLE ln_xyzm (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -27;
+      }
+    sql =
+	"SELECT AddGeometryColumn('ln_xyzm', 'geom', 4326, 'LINESTRING', 'XYZM')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -28;
+      }
+/* populating the input table Linestring XYZM */
+    sql = "INSERT INTO ln_xyzm (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('LINESTRINGZM(0 0 0 0, 1 1 1 1)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -29;
+      }
+
+/* creating the input table Polygon XYZ */
+    sql = "CREATE TABLE pg_xyz (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -30;
+      }
+    sql = "SELECT AddGeometryColumn('pg_xyz', 'geom', 4326, 'POLYGON', 'XYZ')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -31;
+      }
+/* populating the input table Linestring XYZ */
+    sql = "INSERT INTO pg_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POLYGONZ(0 0 0, 0 1 1, 1 1 1, 1 0 1, 0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -32;
+      }
+
+/* creating the input table Polygon XYM */
+    sql = "CREATE TABLE pg_xym (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -33;
+      }
+    sql = "SELECT AddGeometryColumn('pg_xym', 'geom', 4326, 'POLYGON', 'XYM')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -34;
+      }
+/* populating the input table Linestring XYM */
+    sql = "INSERT INTO pg_xym (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POLYGONM(0 0 0, 0 1 1, 1 1 1, 1 0 1, 0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -35;
+      }
+
+/* creating the input table Polygon XYZM */
+    sql = "CREATE TABLE pg_xyzm (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -36;
+      }
+    sql =
+	"SELECT AddGeometryColumn('pg_xyzm', 'geom', 4326, 'POLYGON', 'XYZM')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -37;
+      }
+/* populating the input table Linestring XYZM */
+    sql = "INSERT INTO pg_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POLYGONZM(0 0 0 0, 0 1 1 1, 1 1 1 1, 1 0 1 1, 0 0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -38;
+      }
+
+/* creating the input table Point XY */
+    sql = "CREATE TABLE pt_xy (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -39;
+      }
+    sql = "SELECT AddGeometryColumn('pt_xy', 'geom', 4326, 'POINT', 'XY', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -40;
+      }
+/* populating the input table Point XY */
+    sql = "INSERT INTO pt_xy (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINT(0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -41;
+      }
+
+/* creating the input table Point XYZ */
+    sql = "CREATE TABLE pt_xyz (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -42;
+      }
+    sql = "SELECT AddGeometryColumn('pt_xyz', 'geom', 4326, 'POINT', 'XYZ', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -43;
+      }
+/* populating the input table Point XYZ */
+    sql = "INSERT INTO pt_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTZ(0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -44;
+      }
+
+/* creating the input table Point XYM */
+    sql = "CREATE TABLE pt_xym (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -45;
+      }
+    sql = "SELECT AddGeometryColumn('pt_xym', 'geom', 4326, 'POINT', 'XYM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -46;
+      }
+/* populating the input table Point XYM */
+    sql = "INSERT INTO pt_xym (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTM(0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -47;
+      }
+
+/* creating the input table Point XYZM */
+    sql = "CREATE TABLE pt_xyzm (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -48;
+      }
+    sql =
+	"SELECT AddGeometryColumn('pt_xyzm', 'geom', 4326, 'POINT', 'XYZM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -49;
+      }
+/* populating the input table Point XYZM */
+    sql = "INSERT INTO pt_xyzm (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTZM(0 0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -50;
+      }
+
+/* creating the input table GeometryCollection XY */
+    sql = "CREATE TABLE gc_xy (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -51;
+      }
+    sql =
+	"SELECT AddGeometryColumn('gc_xy', 'geom', 4326, 'GEOMETRYCOLLECTION', 'XY', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -52;
+      }
+/* populating the input table GeometryCollection XY */
+    sql = "INSERT INTO gc_xy (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('GEOMETRYCOLLECTION(POINT(0 0))', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -53;
+      }
+
+/* creating the input table GeometryCollection XYZ */
+    sql = "CREATE TABLE gc_xyz (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -54;
+      }
+    sql =
+	"SELECT AddGeometryColumn('gc_xyz', 'geom', 4326, 'GEOMETRYCOLLECTION', 'XYZ', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -55;
+      }
+/* populating the input table GeometryCollection XYZ */
+    sql = "INSERT INTO gc_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('GEOMETRYCOLLECTIONZ(POINTZ(0 0 0))', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -56;
+      }
+
+/* creating the input table GeometryCollection XYM */
+    sql = "CREATE TABLE gc_xym (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -57;
+      }
+    sql =
+	"SELECT AddGeometryColumn('gc_xym', 'geom', 4326, 'GEOMETRYCOLLECTION', 'XYM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -58;
+      }
+/* populating the input table GeometryCollection XYM */
+    sql = "INSERT INTO gc_xym (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('GEOMETRYCOLLECTIONM(POINTM(0 0 0))', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -59;
+      }
+
+/* creating the input table GeometryCollection XYZM */
+    sql = "CREATE TABLE gc_xyzm (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -60;
+      }
+    sql =
+	"SELECT AddGeometryColumn('gc_xyzm', 'geom', 4326, 'GEOMETRYCOLLECTION', 'XYZM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -61;
+      }
+/* populating the input table GeometryCollection XYZM */
+    sql = "INSERT INTO gc_xyzm (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('GEOMETRYCOLLECTIONZM(POINTZM(0 0 0 0))', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -62;
+      }
+
+/* creating the input table Geometry XY */
+    sql = "CREATE TABLE geo_xy (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -63;
+      }
+    sql =
+	"SELECT AddGeometryColumn('geo_xy', 'geom', 4326, 'GEOMETRY', 'XY', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -64;
+      }
+/* populating the input table Geometry XY */
+    sql = "INSERT INTO geo_xy (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINT(0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -65;
+      }
+
+/* creating the input table Geometry XYZ */
+    sql = "CREATE TABLE geo_xyz (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -66;
+      }
+    sql =
+	"SELECT AddGeometryColumn('geo_xyz', 'geom', 4326, 'GEOMETRY', 'XYZ', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -67;
+      }
+/* populating the input table Geometry XYZ */
+    sql = "INSERT INTO geo_xyz (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTZ(0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -68;
+      }
+
+/* creating the input table Geometry XYM */
+    sql = "CREATE TABLE geo_xym (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -69;
+      }
+    sql =
+	"SELECT AddGeometryColumn('geo_xym', 'geom', 4326, 'GEOMETRY', 'XYM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -70;
+      }
+/* populating the input table Geometry XYM */
+    sql = "INSERT INTO geo_xym (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTM(0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -71;
+      }
+
+/* creating the input table Geometry XYZM */
+    sql = "CREATE TABLE geo_xyzm (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -72;
+      }
+    sql =
+	"SELECT AddGeometryColumn('geo_xyzm', 'geom', 4326, 'GEOMETRY', 'XYZM', 1)";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -73;
+      }
+/* populating the input table Geometry XYZM */
+    sql = "INSERT INTO geo_xyzm (id, name, geom) VALUES "
+	"(NULL, 'one', GeomFromText('POINTZM(0 0 0 0)', 4326))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -74;
+      }
+
+/* creating the input table #5 (append) */
+    sql = "CREATE TABLE input_5 (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+	"name TEXT, code_2 TEXT NOT NULL, "
+	"code_3 TEXT NOT NULL, code_1 TEXT NOT NULL, tbl_3 INTEGER, "
+	"ignore_1 TEXT DEFAULT 'foo', ignore_2 TEXT DEFAULT 'foo', "
+	"ignore_3 TEXT DEFAULT 'foo', ignore_4 TEXT DEFAULT 'foo', "
+	"extra_1 TEXT DEFAULT 'extra_foo', extra_2 TEXT DEFAULT 'extra_foo', "
+	"extra_3 TEXT DEFAULT 'extra_foo', extra_4 TEXT DEFAULT 'extra_foo', "
+	"extra_5 TEXT DEFAULT 'extra_foo', extra_6 TEXT DEFAULT 'extra_foo', "
+	"extra_7 TEXT DEFAULT 'extra_foo', extra_8 TEXT DEFAULT 'extra_foo', "
+	"extra_9 TEXT DEFAULT 'extra_foo', extra_10 TEXT DEFAULT 'extra_foo')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -75;
+      }
+    sql = "SELECT AddGeometryColumn('input_5', 'geom', 4326, 'POINT', 'XY')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -76;
+      }
+    sql =
+	"SELECT AddGeometryColumn('input_5', 'extra_geom', 4326, 'LINESTRING', 'XY')";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -77;
+      }
+
+/* populating the input table #5 */
+    sql =
+	"INSERT INTO input_5 (id, name, code_2, code_3, code_1, geom, extra_geom) VALUES "
+	"(NULL, 'phi', 'it', '01', 'aa', MakePoint(0.5, 0.5, 4326), "
+	"MakeLine(MakePoint(10, 10, 4326), MakePoint(11, 11, 4326))), "
+	"(NULL, 'chi', 'fr', 'zz', 'kk', MakePoint(1.5, 1.5, 4326), "
+	"MakeLine(MakePoint(11, 11, 4326), MakePoint(12, 12, 4326))), "
+	"(NULL, 'psi', 'uk', 'cc', 'bb', MakePoint(2.5, 2.5, 4326), "
+	"MakeLine(MakePoint(12, 12, 4326), MakePoint(13, 13, 4326))), "
+	"(100, 'omega', 'de', 'nn', 'mm', MakePoint(3.5, 3.5, 4326), "
+	"MakeLine(MakePoint(13, 13, 4326), MakePoint(14, 14, 4326)))";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -78;
+      }
+
+    ret = sqlite3_close (handle);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_close() error: %s\n",
+		   sqlite3_errmsg (handle));
+	  return -79;
+      }
+
+    spatialite_cleanup_ex (cache);
+
+    return 0;
+}
+
+int
+test_clone_table (int base, int with_extra, int ignore, int resequence,
+		  int cast2multi)
+{
+/* performing a CloneTable testcase */
+    int ret;
+    sqlite3 *handle;
+    char *err_msg = NULL;
+    const char *sql;
+    int retcode = 0;
+    void *cache = spatialite_alloc_connection ();
+
+    ret =
+	sqlite3_open_v2 (":memory:", &handle,
+			 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "cannot open in-memory database: %s\n",
+		   sqlite3_errmsg (handle));
+	  sqlite3_close (handle);
+	  retcode = -1;
+	  goto end;
+      }
+
+    spatialite_init_ex (handle, cache, 0);
+
+    ret =
+	sqlite3_exec (handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  sqlite3_close (handle);
+	  retcode = -2;
+	  goto end;
+      }
+
+/* attaching the origin DB */
+    sql = "ATTACH DATABASE \"./clone_origin.sqlite\" AS \"input\"";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -3;
+      }
+
+/* cloning input_1 */
+    if (with_extra)
+	sql =
+	    "SELECT CloneTable('input', 'input_1', 'input_1', 1, '::with-foreign-keys::', '::with-triggers::')";
+    else
+	sql = "SELECT CloneTable('input', 'input_1', 'input_1', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -4;
+      }
+
+/* cloning input_2 */
+    if (with_extra)
+	sql =
+	    "SELECT CloneTable('input', 'input_2', 'input_2', 1, '::with-foreign-keys::', '::with-triggers::')";
+    else
+	sql = "SELECT CloneTable('input', 'input_2', 'input_2', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -5;
+      }
+
+/* cloning input_3 */
+    if (with_extra)
+	sql =
+	    "SELECT CloneTable('input', 'input_3', 'input_3', 1, '::with-foreign-keys::', '::with-triggers::')";
+    else if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'input_3', 'input_3', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'input_3', 'input_3', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -6;
+      }
+
+/* cloning input_4 */
+    if (with_extra)
+	sql =
+	    "SELECT CloneTable('input', 'input_4', 'input_4', 1, '::with-foreign-keys::', '::with-triggers::')";
+    else if (ignore)
+	sql =
+	    "SELECT CloneTable('input', 'input_4', 'input_4', 1, '::ignore::ignore_1', '::ignore::ignore_2', "
+	    "'::ignore::ignore_3', '::ignore::ignore_4', '::ignore::ignore_5', '::ignore::ignore_6', "
+	    "'::ignore::ignore_7', '::ignore::ignore_8', '::ignore::ignore_9', '::ignore::ignore_10')";
+    else if (resequence)
+	sql =
+	    "SELECT CloneTable('input', 'input_4', 'input_4', 1, '::resequence::')";
+    else
+	sql = "SELECT CloneTable('input', 'input_4', 'input_4', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -7;
+      }
+
+/* cloning Linestring XY */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'ln_xy', 'ln_xy', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'ln_xy', 'ln_xy', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -8;
+      }
+
+/* cloning Linestring XYZ */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'ln_xyz', 'ln_xyz', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'ln_xyz', 'ln_xyz', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -9;
+      }
+
+/* cloning Linestring XYM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'ln_xym', 'ln_xym', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'ln_xym', 'ln_xym', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -10;
+      }
+
+/* cloning Linestring XYZM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'ln_xyzm', 'ln_xyzm', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'ln_xyzm', 'ln_xyzm', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -11;
+      }
+
+/* cloning Polygon XYZ */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pg_xyz', 'pg_xyz', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pg_xyz', 'pg_xyz', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -12;
+      }
+
+/* cloning Polygon XYM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pg_xym', 'pg_xym', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pg_xym', 'pg_xym', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -13;
+      }
+
+/* cloning Polygon XYZM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pg_xyzm', 'pg_xyzm', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pg_xyzm', 'pg_xyzm', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -14;
+      }
+
+/* cloning Point XY */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pt_xy', 'pt_xy', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pt_xy', 'pt_xy', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -15;
+      }
+
+/* cloning Point XYZ */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pt_xyz', 'pt_xyz', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pt_xyz', 'pt_xyz', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -16;
+      }
+
+/* cloning Point XYM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pt_xym', 'pt_xym', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pt_xym', 'pt_xym', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -17;
+      }
+
+/* cloning Point XYZM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'pt_xyzm', 'pt_xyzm', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'pt_xyzm', 'pt_xyzm', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -18;
+      }
+
+/* cloning GeometryCollection XY */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'gc_xy', 'gc_xy', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'gc_xy', 'gc_xy', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -19;
+      }
+
+/* cloning GeometryCollection XYZ */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'gc_xyz', 'gc_xyz', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'gc_xyz', 'gc_xyz', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -20;
+      }
+
+/* cloning GeometryCollection XYM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'gc_xym', 'gc_xym', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'gc_xym', 'gc_xym', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -21;
+      }
+
+/* cloning GeometryCollection XYZM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'gc_xyzm', 'gc_xyzm', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'gc_xyzm', 'gc_xyzm', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -22;
+      }
+
+/* cloning Geometry XY */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'geo_xy', 'geo_xy', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'geo_xy', 'geo_xy', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -23;
+      }
+
+/* cloning Geometry XYZ */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'geo_xyz', 'geo_xyz', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'geo_xyz', 'geo_xyz', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -24;
+      }
+
+/* cloning Geometry XYM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'geo_xym', 'geo_xym', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'geo_xym', 'geo_xym', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -25;
+      }
+
+/* cloning Geometry XYZM */
+    if (cast2multi)
+	sql =
+	    "SELECT CloneTable('input', 'geo_xyzm', 'geo_xyzm', 1, '::cast2multi::geom')";
+    else
+	sql = "SELECT CloneTable('input', 'geo_xyzm', 'geo_xyzm', 1)";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -22;
+      }
+
+/* cloning input_5 (APPEND) */
+    if (ignore)
+	sql =
+	    "SELECT CloneTable('input', 'input_5', 'input_4', 1, '::ignore::ignore_1', '::ignore::ignore_2', "
+	    "'::ignore::ignore_3', '::ignore::ignore_4', '::resequence::', '::append::', "
+	    "'::ignore::extra_7', '::ignore::extra_8', '::ignore::extra_9', '::ignore::extra_10')";
+    else
+	sql =
+	    "SELECT CloneTable('input', 'input_5', 'input_4', 1, '::resequence::', '::append::')";
+    ret = execute_check (handle, sql, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -23;
+      }
+
+/* detaching the origin DB */
+    sql = "DETACH DATABASE \"input\"";
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -12;
+      }
+
+    ret = sqlite3_close (handle);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_close() error: %s\n",
+		   sqlite3_errmsg (handle));
+	  retcode = -9;
+	  goto end;
+      }
+
+    spatialite_cleanup_ex (cache);
+
+  end:
+    if (retcode < 0)
+	return base + retcode;
+    return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+    int ret;
+    int retcode = 0;
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+    if (create_origin () < 0)
+      {
+	  retcode = -66;
+	  goto end;
+      }
+
+/* base test: no options */
+    ret = test_clone_table (-100, 0, 0, 0, 0);
+    if (ret < 0)
+      {
+	  retcode = ret;
+	  goto end;
+      }
+/* advanced test: with-foreign-keys and with-triggers */
+    ret = test_clone_table (-200, 1, 0, 0, 0);
+    if (ret < 0)
+      {
+	  retcode = ret;
+	  goto end;
+      }
+/* advanced test: ignore */
+    ret = test_clone_table (-300, 0, 1, 0, 0);
+    if (ret < 0)
+      {
+	  retcode = ret;
+	  goto end;
+      }
+/* advanced test: resequence */
+    ret = test_clone_table (-400, 0, 0, 1, 0);
+    if (ret < 0)
+      {
+	  retcode = ret;
+	  goto end;
+      }
+/* advanced test: cast2multi */
+    ret = test_clone_table (-400, 0, 0, 0, 1);
+    if (ret < 0)
+      {
+	  retcode = ret;
+	  goto end;
+      }
+
+  end:
+/* removing the origin DB */
+    unlink ("clone_origin.sqlite");
+    spatialite_shutdown ();
+    return retcode;
+}
diff --git a/test/check_dxf.c b/test/check_dxf.c
index 468507c..99592d6 100644
--- a/test/check_dxf.c
+++ b/test/check_dxf.c
@@ -61,7 +61,7 @@ check_22_auto (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -164,7 +164,7 @@ check_22_2d (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -267,7 +267,7 @@ check_22_3d (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -370,7 +370,7 @@ check_22_single (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -474,7 +474,7 @@ check_merano (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -665,7 +665,7 @@ check_archaic (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -770,7 +770,7 @@ check_linked (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -873,7 +873,7 @@ check_linked_legacy (int cache_mode)
     int ret;
     sqlite3 *handle;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -981,7 +981,7 @@ check_hatch (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -1084,7 +1084,7 @@ check_hatch_legacy (int cache_mode)
     int ret;
     sqlite3 *handle;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -1189,7 +1189,7 @@ check_symbol (int cache_mode)
     sqlite3 *handle;
     char *err_msg = NULL;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
@@ -1292,7 +1292,7 @@ check_symbol_legacy (int cache_mode)
     int ret;
     sqlite3 *handle;
     gaiaDxfParserPtr dxf;
-    void *cache;
+    void *cache = NULL;
     if (cache_mode)
 	cache = spatialite_alloc_connection ();
     else
diff --git a/test/check_spatialindex.c b/test/check_spatialindex.c
index 1463fe9..8a6f056 100644
--- a/test/check_spatialindex.c
+++ b/test/check_spatialindex.c
@@ -459,6 +459,16 @@ do_test (sqlite3 * handle, int legacy)
 	  sqlite3_free (err_msg);
 	  return -9;
       }
+    ret =
+	sqlite3_exec (handle,
+		      "SELECT UpgradeGeometryTriggers(1);",
+		      NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "UpgradeGeometryTriggers (1) error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -101;
+      }
 
     rows = 0;
     columns = 0;
diff --git a/test/check_sql_stmt.c b/test/check_sql_stmt.c
index 572d8c1..631c9d1 100644
--- a/test/check_sql_stmt.c
+++ b/test/check_sql_stmt.c
@@ -618,7 +618,7 @@ run_all_testcases (struct db_conn *conn, int load_extension)
     else if (strcasecmp (security_level, "relaxed") == 0)
       {
 	  result =
-	      run_subdir_test ("sql_stmt_libxml2_tests", conn, load_extension);
+	      run_subdir_test ("sql_stmt_xmlsec_tests", conn, load_extension);
 	  if (result != 0)
 	    {
 		return result;
@@ -637,6 +637,21 @@ run_all_testcases (struct db_conn *conn, int load_extension)
 
 #endif /* end GEOPACKAGE conditional */
 
+#ifndef OMIT_FREEXL		/* FREEXL is enabled */
+    security_level = getenv ("SPATIALITE_SECURITY");
+    if (security_level == NULL)
+	;
+    else if (strcasecmp (security_level, "relaxed") == 0)
+      {
+	  result =
+	      run_subdir_test ("sql_stmt_freexl_tests", conn, load_extension);
+	  if (result != 0)
+	    {
+		return result;
+	    }
+      }
+#endif /* end FREEXL support */
+
     return result;
 }
 
diff --git a/test/check_virtualelem.c b/test/check_virtualelem.c
new file mode 100644
index 0000000..1388b5a
--- /dev/null
+++ b/test/check_virtualelem.c
@@ -0,0 +1,1134 @@
+/*
+
+ check_virtualelem.c -- SpatiaLite Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the SpatiaLite library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+static int
+create_table (sqlite3 * sqlite, const char *table)
+{
+/* creating a test table */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+
+    sql =
+	sqlite3_mprintf
+	("CREATE TABLE %s (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+	 "name TEXT NOT NULL)", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CREATE TABLE \"%s\" error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
+test_table (sqlite3 * sqlite, const char *prefix, const char *table,
+	    const char *column)
+{
+/* testing a resultset */
+    int ret;
+    char *sql;
+    sqlite3_stmt *stmt = NULL;
+    int row_no = 0;
+
+    if (prefix == NULL && column == NULL)
+	sql = sqlite3_mprintf ("SELECT t.id, t.name, Count(e.geometry) "
+			       "FROM %s AS t JOIN ElementaryGeometries AS e ON "
+			       "(e.f_table_name = %Q AND e.origin_rowid = t.ROWID) "
+			       "GROUP BY t.id", table, table);
+    else if (prefix != NULL && column != NULL)
+	sql = sqlite3_mprintf ("SELECT t.id, t.name, Count(e.geometry) "
+			       "FROM %s AS t JOIN ElementaryGeometries AS e ON "
+			       "(e.db_prefix = %Q AND e.f_table_name = %Q AND "
+			       "e.f_geometry_column = %Q AND e.origin_rowid = t.ROWID) "
+			       "GROUP BY t.id", table, prefix, table, column);
+    else if (prefix != NULL)
+	sql = sqlite3_mprintf ("SELECT t.id, t.name, Count(e.geometry) "
+			       "FROM %s AS t JOIN ElementaryGeometries AS e ON "
+			       "(e.db_prefix = %Q AND e.f_table_name = %Q "
+			       "AND e.origin_rowid = t.ROWID) "
+			       "GROUP BY t.id", table, prefix, table);
+    else
+	sql = sqlite3_mprintf ("SELECT t.id, t.name, Count(e.geometry) "
+			       "FROM %s AS t JOIN ElementaryGeometries AS e ON "
+			       "(e.f_table_name = %Q AND e.f_geometry_column = %Q "
+			       "AND e.origin_rowid = t.ROWID) "
+			       "GROUP BY t.id", table, table, column);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SELECT FROM \"%s\": \"%s\"\n", table,
+		   sqlite3_errmsg (sqlite));
+	  return 0;
+      }
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		int id = sqlite3_column_int (stmt, 0);
+		const char *name = (const char *) sqlite3_column_text (stmt, 1);
+		int count = sqlite3_column_int (stmt, 2);
+		switch (row_no)
+		  {
+		  case 0:
+		      if (id == 1 && strcmp (name, "alpha") == 0 && count == 1)
+			  ;
+		      else
+			{
+			    fprintf (stderr,
+				     "Unexpected result: table \"%s\" row=%d) [%d %s %d]\n",
+				     table, row_no, id, name, count);
+			    goto error;
+			}
+		      break;
+		  case 1:
+		      if (id == 2 && strcmp (name, "beta") == 0 && count == 2)
+			  ;
+		      else
+			{
+			    fprintf (stderr,
+				     "Unexpected result: table \"%s\" row=%d) [%d %s %d]\n",
+				     table, row_no, id, name, count);
+			    goto error;
+			}
+		      break;
+		  case 2:
+		      if (id == 3 && strcmp (name, "gamma") == 0 && count == 3)
+			  ;
+		      else
+			{
+			    fprintf (stderr,
+				     "Unexpected result: table \"%s\" row=%d) [%d %s %d]\n",
+				     table, row_no, id, name, count);
+			    goto error;
+			}
+		      break;
+		  default:
+		      fprintf (stderr, "Unexpected row %d (table \"%s\")\n",
+			       row_no, table);
+		      goto error;
+		  };
+	    }
+	  else
+	      goto error;
+	  row_no++;
+      }
+    sqlite3_finalize (stmt);
+    return 1;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return 0;
+}
+
+static int
+test_point_xy (sqlite3 * sqlite)
+{
+/* testing MULTIPOINT XY */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpointxy";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOINT', 'XY')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOINT(1 1)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOINT(1 1, 2 2)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOINT(1 1, 2 2, 3 3)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_point_xyz (sqlite3 * sqlite)
+{
+/* testing MULTIPOINT XYZ */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpointxyz";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOINT', 'XYZ')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOINTZ(1 1 1)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOINTZ(1 1 1, 2 2 2)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOINTZ(1 1 1, 2 2 2, 3 3 3)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_point_xym (sqlite3 * sqlite)
+{
+/* testing MULTIPOINT XYM */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpointxym";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOINT', 'XYM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOINTM(1 1 1)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOINTM(1 1 1, 2 2 2)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOINTM(1 1 1, 2 2 2, 3 3 3)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_point_xyzm (sqlite3 * sqlite)
+{
+/* testing MULTIPOINT XYZM */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpointxyzm";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOINT', 'XYZM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOINTZM(1 1 1 1)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOINTZM(1 1 1 1, 2 2 2 2)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOINTZM(1 1 1 1, 2 2 2 2, 3 3 3 3)', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_linestring_xy (sqlite3 * sqlite)
+{
+/* testing MULTILINESTRING XY */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mlinestringxy";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTILINESTRING', 'XY')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTILINESTRING((1 1, 2 2))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTILINESTRING((1 1, 2 2), "
+			   "(3 3, 4 4))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTILINESTRING((1 1, 2 2), "
+			   "(3 3, 4 4), (5 5, 6 6))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_linestring_xyz (sqlite3 * sqlite)
+{
+/* testing MULTILINESTRING XYZ */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mlinestringxyz";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTILINESTRING', 'XYZ')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTILINESTRINGZ((1 1 1, 2 2 2))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTILINESTRINGZ((1 1 1, 2 2 2), "
+			   "(3 3 3, 4 4 4))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTILINESTRINGZ((1 1 1, 2 2 2), "
+			   "(3 3 3, 4 4 4), (5 5 5, 6 6 6))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_linestring_xym (sqlite3 * sqlite)
+{
+/* testing MULTILINESTRING XYM */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mlinestringxym";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTILINESTRING', 'XYM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTILINESTRINGM((1 1 1, 2 2 2))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTILINESTRINGM((1 1 1, 2 2 2), "
+			   "(3 3 3, 4 4 4))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTILINESTRINGM((1 1 1, 2 2 2), "
+			   "(3 3 3, 4 4 4), (5 5 5, 6 6 6))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_linestring_xyzm (sqlite3 * sqlite)
+{
+/* testing MULTILINESTRING XYZ */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mlinestringxyzm";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTILINESTRING', 'XYZM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTILINESTRINGZM((1 1 1 1, 2 2 2 2))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTILINESTRINGZM((1 1 1 1, 2 2 2 2), "
+			   "(3 3 3 3, 4 4 4 4))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTILINESTRINGZM((1 1 1 1, 2 2 2 2), "
+			   "(3 3 3 3, 4 4 4 4), (5 5 5 5, 6 6 6 6))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_polygon_xy (sqlite3 * sqlite)
+{
+/* testing MULTIPOLYGON XY */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpolygonxy";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOLYGON', 'XY')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOLYGON("
+			   "((1 1, 2 1, 2 2, 1 2, 1 1)))', 4326))", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOLYGON("
+			   "((1 1, 2 1, 2 2, 1 2, 1 1)), "
+			   "((10 10, 11 10, 11 11, 10 11, 10 10)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOLYGON("
+			   "((1 1, 2 1, 2 2, 1 2, 1 1)), "
+			   "((10 10, 11 10, 11 11, 10 11, 10 10)), "
+			   "((20 20, 31 20, 31 31, 20 31, 20 20), "
+			   "(25 25, 25 26, 26 26, 26 25, 25 25)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_polygon_xyz (sqlite3 * sqlite)
+{
+/* testing MULTIPOLYGON XYZ */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpolygonxyz";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOLYGON', 'XYZ')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOLYGONZ("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOLYGONZ("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)), "
+			   "((10 10 10, 11 10 10, 11 11 11, 10 11 11, 10 10 10)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOLYGONZ("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)), "
+			   "((10 10 10, 11 10 10, 11 11 11, 10 11 11, 10 10 10)), "
+			   "((20 20 20, 31 20 20, 31 31 31, 20 31 31, 20 20 20), "
+			   "(25 25 25, 25 26 26, 26 26 26, 26 25 25, 25 25 25)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_polygon_xym (sqlite3 * sqlite)
+{
+/* testing MULTIPOLYGON XYM */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpolygonxym";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOLYGON', 'XYM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOLYGONM("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOLYGONM("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)), "
+			   "((10 10 10, 11 10 10, 11 11 11, 10 11 11, 10 10 10)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOLYGONM("
+			   "((1 1 1, 2 1 1, 2 2 2, 1 2 2, 1 1 1)), "
+			   "((10 10 10, 11 10 10, 11 11 11, 10 11 11, 10 10 10)), "
+			   "((20 20 20, 31 20 20, 31 31 31, 20 31 31, 20 20 20), "
+			   "(25 25 25, 25 26 26, 26 26 26, 26 25 25, 25 25 25)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, "main", table, NULL);
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+static int
+test_polygon_xyzm (sqlite3 * sqlite)
+{
+/* testing MULTIPOLYGON XYZM */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    const char *table = "mpolygonxyzm";
+
+/* creating the base Table */
+    ret = create_table (sqlite, table);
+    if (!ret)
+	return 0;
+/* adding the Geometry */
+    sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, 'geom', 4326, "
+			   "'MULTIPOLYGON', 'XYZM')", table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n", table,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+/* populating the test table */
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'alpha', ST_GeomFromText('MULTIPOLYGONZM("
+			   "((1 1 1 1, 2 1 1 1, 2 2 2 2, 1 2 2 2, 1 1 1 1)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #1 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'beta', ST_GeomFromText('MULTIPOLYGONZM("
+			   "((1 1 1 1, 2 1 1 1, 2 2 2 2, 1 2 2 2, 1 1 1 1)), "
+			   "((10 10 10 10, 11 10 10 10, 11 11 11 11, 10 11 11 11, 10 10 10 10)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #2 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+    sql = sqlite3_mprintf ("INSERT INTO %s (id, name, geom) VALUES "
+			   "(NULL, 'gamma', ST_GeomFromText('MULTIPOLYGONZM("
+			   "((1 1 1 1, 2 1 1 1, 2 2 2 2, 1 2 2 2, 1 1 1 1)), "
+			   "((10 10 10 10, 11 10 10 10, 11 11 11 11, 10 11 11 11, 10 10 10 10)), "
+			   "((20 20 20 20, 31 20 20 20, 31 31 31 31, 20 31 31 31, 20 20 20 20), "
+			   "(25 25 25 25, 25 26 26 26, 26 26 26 26, 26 25 25 25, 25 25 25 25)))', 4326))",
+			   table);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, &err_msg);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "INSERT INTO \"%s\" #3 error: %s\n", table, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+/* testing the table */
+    ret = test_table (sqlite, NULL, table, "geom");
+    if (!ret)
+	return 0;
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    sqlite3 *db_handle = NULL;
+    int ret;
+    char *err_msg = NULL;
+    void *cache = spatialite_alloc_connection ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+    ret =
+	sqlite3_open_v2 (":memory:", &db_handle,
+			 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "cannot open in-memory db: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  sqlite3_close (db_handle);
+	  db_handle = NULL;
+	  return -1;
+      }
+
+    spatialite_init_ex (db_handle, cache, 0);
+
+    ret =
+	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  sqlite3_close (db_handle);
+	  return -2;
+      }
+
+/* Testing MULTIPOINTs */
+    ret = test_point_xy (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -3;
+      }
+    ret = test_point_xyz (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -4;
+      }
+    ret = test_point_xym (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -5;
+      }
+    ret = test_point_xyzm (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -6;
+      }
+
+/* Testing MULTILINESTRINGs */
+    ret = test_linestring_xy (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -7;
+      }
+    ret = test_linestring_xyz (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -8;
+      }
+    ret = test_linestring_xym (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -9;
+      }
+    ret = test_linestring_xyzm (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -10;
+      }
+
+/* Testing MULTIPOLYGONs */
+    ret = test_polygon_xy (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -11;
+      }
+    ret = test_polygon_xyz (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -12;
+      }
+    ret = test_polygon_xym (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -13;
+      }
+    ret = test_polygon_xyzm (db_handle);
+    if (!ret)
+      {
+	  sqlite3_close (db_handle);
+	  return -14;
+      }
+
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    spatialite_shutdown ();
+
+    return 0;
+}
diff --git a/test/check_virtualtable3.c b/test/check_virtualtable3.c
index cd2c5d9..cf7e9da 100644
--- a/test/check_virtualtable3.c
+++ b/test/check_virtualtable3.c
@@ -776,7 +776,7 @@ main (int argc, char *argv[])
 
     ret =
 	sqlite3_exec (db_handle,
-		      "create VIRTUAL TABLE toomanyargs USING VirtualDBF(\"shapetest1.dbf\", UTF-8, 1);",
+		      "create VIRTUAL TABLE toomanyargs USING VirtualDBF(\"shapetest1.dbf\", UTF-8, 1, 1);",
 		      NULL, NULL, &err_msg);
     if (ret != SQLITE_ERROR)
       {
diff --git a/test/check_virtualtable6.c b/test/check_virtualtable6.c
index f6b107a..3c176be 100644
--- a/test/check_virtualtable6.c
+++ b/test/check_virtualtable6.c
@@ -254,7 +254,7 @@ main (int argc, char *argv[])
 
     ret =
 	sqlite3_exec (db_handle,
-		      "create VIRTUAL TABLE toomanyargs USING VirtualShape(\"shapetest1\", UTF8, 4386, 1);",
+		      "create VIRTUAL TABLE toomanyargs USING VirtualShape(\"shapetest1\", UTF8, 4386, 1, 1);",
 		      NULL, NULL, &err_msg);
     if (ret != SQLITE_ERROR)
       {
diff --git a/test/sql_stmt_freexl_tests/Makefile.am b/test/sql_stmt_freexl_tests/Makefile.am
new file mode 100644
index 0000000..15ba7eb
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/Makefile.am
@@ -0,0 +1,8 @@
+
+EXTRA_DIST = loadxls1.testcase \
+	loadxls2.testcase \
+	loadxls3.testcase \
+	loadxls4.testcase \
+	loadxls5.testcase \
+	loadxls6.testcase \
+	loadxls7.testcase
diff --git a/test/sql_stmt_security_tests/Makefile.in b/test/sql_stmt_freexl_tests/Makefile.in
similarity index 96%
copy from test/sql_stmt_security_tests/Makefile.in
copy to test/sql_stmt_freexl_tests/Makefile.in
index 4472dcf..9c3561c 100644
--- a/test/sql_stmt_security_tests/Makefile.in
+++ b/test/sql_stmt_freexl_tests/Makefile.in
@@ -77,7 +77,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-subdir = test/sql_stmt_security_tests
+subdir = test/sql_stmt_freexl_tests
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@@ -240,20 +240,13 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = blobfromfile1.testcase \
-	blobfromfile2.testcase \
-	blobfromfile3.testcase \
-	blobfromfile4.testcase \
-	blobtofile1.testcase \
-	blobtofile2.testcase \
-	blobtofile3.testcase \
-	blobtofile4.testcase \
-	isXblob1.testcase \
-	isXblob2.testcase \
-	isXblob3.testcase \
-	isXblob4.testcase \
-	isXblob8.testcase \
-	isXblob9.testcase 
+EXTRA_DIST = loadxls1.testcase \
+	loadxls2.testcase \
+	loadxls3.testcase \
+	loadxls4.testcase \
+	loadxls5.testcase \
+	loadxls6.testcase \
+	loadxls7.testcase
 
 all: all-am
 
@@ -267,9 +260,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/sql_stmt_security_tests/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/sql_stmt_freexl_tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign test/sql_stmt_security_tests/Makefile
+	  $(AUTOMAKE) --foreign test/sql_stmt_freexl_tests/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
diff --git a/test/sql_stmt_freexl_tests/loadxls1.testcase b/test/sql_stmt_freexl_tests/loadxls1.testcase
new file mode 100644
index 0000000..b7588a2
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls1.testcase
@@ -0,0 +1,7 @@
+ImportXLS - NULL filename
+:memory: #use in-memory database
+SELECT ImportXLS(NULL, 'table');
+1 # rows (not including the header row)
+1 # columns
+ImportXLS(NULL, 'table')
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls2.testcase b/test/sql_stmt_freexl_tests/loadxls2.testcase
new file mode 100644
index 0000000..54ca02a
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls2.testcase
@@ -0,0 +1,7 @@
+ImportXLS - NULL table
+:memory: #use in-memory database
+SELECT ImportXLS('spreadsheet.xls', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('spreadsheet.xls', NULL);
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls3.testcase b/test/sql_stmt_freexl_tests/loadxls3.testcase
new file mode 100644
index 0000000..df3addc
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls3.testcase
@@ -0,0 +1,7 @@
+ImportXLS - NULL worksheet_index
+:memory: #use in-memory database
+SELECT ImportXLS('spreadsheet.xls', 'table', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('spreadsheet.xls', 'table', NULL);
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls4.testcase b/test/sql_stmt_freexl_tests/loadxls4.testcase
new file mode 100644
index 0000000..3af7e99
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls4.testcase
@@ -0,0 +1,7 @@
+ImportXLS - NULL first-line-title
+:memory: #use in-memory database
+SELECT ImportXLS('spreadsheet.xls', 'table', 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('spreadsheet.xls', 'table', 1, NULL);
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls5.testcase b/test/sql_stmt_freexl_tests/loadxls5.testcase
new file mode 100644
index 0000000..d7e620b
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls5.testcase
@@ -0,0 +1,7 @@
+ImportXLS - not existing spreadsheet
+:memory: #use in-memory database
+SELECT ImportXLS('spreadsheet.xls', 'table', 1, 1);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('spreadsheet.xls', 'table', 1, 1);
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls6.testcase b/test/sql_stmt_freexl_tests/loadxls6.testcase
new file mode 100644
index 0000000..ee9518b
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls6.testcase
@@ -0,0 +1,7 @@
+ImportXLS - negative worksheet index
+:memory: #use in-memory database
+SELECT ImportXLS('spreadsheet.xls', 'table', -1, 1);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('spreadsheet.xls', 'table', -1, 1);
+(NULL)
diff --git a/test/sql_stmt_freexl_tests/loadxls7.testcase b/test/sql_stmt_freexl_tests/loadxls7.testcase
new file mode 100644
index 0000000..d6f0253
--- /dev/null
+++ b/test/sql_stmt_freexl_tests/loadxls7.testcase
@@ -0,0 +1,7 @@
+ImportXLS - existing spreadsheet
+:memory: #use in-memory database
+SELECT ImportXLS('./testcase1.xls', 'xlstable', 1, 1);
+1 # rows (not including the header row)
+1 # columns
+ImportXLS('./testcase1.xls', 'xlstable', 1, 1);
+19
diff --git a/test/sql_stmt_security_tests/Makefile.am b/test/sql_stmt_security_tests/Makefile.am
index e75ab94..1af1622 100644
--- a/test/sql_stmt_security_tests/Makefile.am
+++ b/test/sql_stmt_security_tests/Makefile.am
@@ -7,6 +7,99 @@ EXTRA_DIST = blobfromfile1.testcase \
 	blobtofile2.testcase \
 	blobtofile3.testcase \
 	blobtofile4.testcase \
+	exportdbf1.testcase \
+	exportdbf2.testcase \
+	exportdbf3.testcase \
+	exportdbf4.testcase \
+	exportdxf1.testcase \
+	exportdxf2.testcase \
+	exportdxf3.testcase \
+	exportdxf4.testcase \
+	exportdxf5.testcase \
+	exportdxf6.testcase \
+	exportdxf7.testcase \
+	exportdxf7.testcase \
+	exportdxf8.testcase \
+	exportdxf9.testcase \
+	exportdxf10.testcase \
+	exportgeojson1.testcase \
+	exportgeojson2.testcase \
+	exportgeojson3.testcase \
+	exportgeojson4.testcase \
+	exportgeojson5.testcase \
+	exportgeojson6.testcase \
+	exportgeojson7.testcase \
+	exportgeojson8.testcase \
+	exportgeojson9.testcase \
+	exportgeojson10.testcase \
+	exportgeojson11.testcase \
+	exportkml1.testcase \
+	exportkml2.testcase \
+	exportkml3.testcase \
+	exportkml4.testcase \
+	exportkml5.testcase \
+	exportkml6.testcase \
+	exportkml7.testcase \
+	exportshp1.testcase \
+	exportshp2.testcase \
+	exportshp3.testcase \
+	exportshp4.testcase \
+	exportshp5.testcase \
+	exportshp6.testcase \
+	exportdxf11.testcase \
+	importdbf1.testcase \
+	importdbf2.testcase \
+	importdbf3.testcase \
+	importdbf4.testcase \
+	importdbf5.testcase \
+	importdbf6.testcase \
+	importdbf7.testcase \
+	importdxf1.testcase \
+	importdxf2.testcase \
+	importdxf3.testcase \
+	importdxf4.testcase \
+	importdxf5.testcase \
+	importdxf6.testcase \
+	importdxf7.testcase \
+	importdxf8.testcase \
+	importdxf9.testcase \
+	importdxf10.testcase \
+	importdxf11.testcase \
+	importdxf12.testcase \
+	importdxf13.testcase \
+	importdxf14.testcase \
+	importdxf15.testcase \
+	importdxf16.testcase \
+	importdxfdir1.testcase \
+	importdxfdir2.testcase \
+	importdxfdir3.testcase \
+	importdxfdir4.testcase \
+	importdxfdir5.testcase \
+	importdxfdir6.testcase \
+	importdxfdir7.testcase \
+	importdxfdir8.testcase \
+	importdxfdir9.testcase \
+	importdxfdir10.testcase \
+	importdxfdir11.testcase \
+	importdxfdir12.testcase \
+	importdxfdir13.testcase \
+	importdxfdir14.testcase \
+	importdxfdir15.testcase \
+	importdxfdir16.testcase \
+	importshp1.testcase \
+	importshp2.testcase \
+	importshp3.testcase \
+	importshp4.testcase \
+	importshp5.testcase \
+	importshp6.testcase \
+	importshp7.testcase \
+	importshp8.testcase \
+	importshp9.testcase \
+	importshp10.testcase \
+	importshp11.testcase \
+	importshp12.testcase \
+	importshp13.testcase \
+	importshp14.testcase \
 	isXblob1.testcase \
 	isXblob2.testcase \
 	isXblob3.testcase \
diff --git a/test/sql_stmt_security_tests/Makefile.in b/test/sql_stmt_security_tests/Makefile.in
index 4472dcf..0e921cb 100644
--- a/test/sql_stmt_security_tests/Makefile.in
+++ b/test/sql_stmt_security_tests/Makefile.in
@@ -248,6 +248,99 @@ EXTRA_DIST = blobfromfile1.testcase \
 	blobtofile2.testcase \
 	blobtofile3.testcase \
 	blobtofile4.testcase \
+	exportdbf1.testcase \
+	exportdbf2.testcase \
+	exportdbf3.testcase \
+	exportdbf4.testcase \
+	exportdxf1.testcase \
+	exportdxf2.testcase \
+	exportdxf3.testcase \
+	exportdxf4.testcase \
+	exportdxf5.testcase \
+	exportdxf6.testcase \
+	exportdxf7.testcase \
+	exportdxf7.testcase \
+	exportdxf8.testcase \
+	exportdxf9.testcase \
+	exportdxf10.testcase \
+	exportgeojson1.testcase \
+	exportgeojson2.testcase \
+	exportgeojson3.testcase \
+	exportgeojson4.testcase \
+	exportgeojson5.testcase \
+	exportgeojson6.testcase \
+	exportgeojson7.testcase \
+	exportgeojson8.testcase \
+	exportgeojson9.testcase \
+	exportgeojson10.testcase \
+	exportgeojson11.testcase \
+	exportkml1.testcase \
+	exportkml2.testcase \
+	exportkml3.testcase \
+	exportkml4.testcase \
+	exportkml5.testcase \
+	exportkml6.testcase \
+	exportkml7.testcase \
+	exportshp1.testcase \
+	exportshp2.testcase \
+	exportshp3.testcase \
+	exportshp4.testcase \
+	exportshp5.testcase \
+	exportshp6.testcase \
+	exportdxf11.testcase \
+	importdbf1.testcase \
+	importdbf2.testcase \
+	importdbf3.testcase \
+	importdbf4.testcase \
+	importdbf5.testcase \
+	importdbf6.testcase \
+	importdbf7.testcase \
+	importdxf1.testcase \
+	importdxf2.testcase \
+	importdxf3.testcase \
+	importdxf4.testcase \
+	importdxf5.testcase \
+	importdxf6.testcase \
+	importdxf7.testcase \
+	importdxf8.testcase \
+	importdxf9.testcase \
+	importdxf10.testcase \
+	importdxf11.testcase \
+	importdxf12.testcase \
+	importdxf13.testcase \
+	importdxf14.testcase \
+	importdxf15.testcase \
+	importdxf16.testcase \
+	importdxfdir1.testcase \
+	importdxfdir2.testcase \
+	importdxfdir3.testcase \
+	importdxfdir4.testcase \
+	importdxfdir5.testcase \
+	importdxfdir6.testcase \
+	importdxfdir7.testcase \
+	importdxfdir8.testcase \
+	importdxfdir9.testcase \
+	importdxfdir10.testcase \
+	importdxfdir11.testcase \
+	importdxfdir12.testcase \
+	importdxfdir13.testcase \
+	importdxfdir14.testcase \
+	importdxfdir15.testcase \
+	importdxfdir16.testcase \
+	importshp1.testcase \
+	importshp2.testcase \
+	importshp3.testcase \
+	importshp4.testcase \
+	importshp5.testcase \
+	importshp6.testcase \
+	importshp7.testcase \
+	importshp8.testcase \
+	importshp9.testcase \
+	importshp10.testcase \
+	importshp11.testcase \
+	importshp12.testcase \
+	importshp13.testcase \
+	importshp14.testcase \
 	isXblob1.testcase \
 	isXblob2.testcase \
 	isXblob3.testcase \
diff --git a/test/sql_stmt_security_tests/exportdbf1.testcase b/test/sql_stmt_security_tests/exportdbf1.testcase
new file mode 100644
index 0000000..57d2139
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdbf1.testcase
@@ -0,0 +1,7 @@
+exportDBF - NULL table
+:memory: #use in-memory database
+SELECT ExportDBF(NULL, 'test.dbf', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportDBF(NULL, 'test.dbf', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportdbf2.testcase b/test/sql_stmt_security_tests/exportdbf2.testcase
new file mode 100644
index 0000000..8a4bee5
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdbf2.testcase
@@ -0,0 +1,7 @@
+exportDBF - NULL filename
+:memory: #use in-memory database
+SELECT ExportDBF('table', NULL, 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportDBF('table', NULL, 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportdbf3.testcase b/test/sql_stmt_security_tests/exportdbf3.testcase
new file mode 100644
index 0000000..e648be3
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdbf3.testcase
@@ -0,0 +1,7 @@
+exportDBF - NULL charset
+:memory: #use in-memory database
+SELECT ExportDBF('table', 'test.dbf', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportDBF('table', 'test.dbf', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportdbf4.testcase b/test/sql_stmt_security_tests/exportdbf4.testcase
new file mode 100644
index 0000000..dff0d17
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdbf4.testcase
@@ -0,0 +1,7 @@
+exportDBF - not existing table
+:memory: #use in-memory database
+SELECT ExportDBF('table', 'test.dbf', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportDBF('table', 'test.dbf', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportdxf1.testcase b/test/sql_stmt_security_tests/exportdxf1.testcase
new file mode 100644
index 0000000..7210ac1
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf1.testcase
@@ -0,0 +1,7 @@
+exportDXF - null directory
+:memory: #use in-memory database
+SELECT ExportDXF(NULL, 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF(NULL, 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf10.testcase b/test/sql_stmt_security_tests/exportdxf10.testcase
new file mode 100644
index 0000000..00398ce
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf10.testcase
@@ -0,0 +1,7 @@
+exportDXF - invalid BBOX
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', zeroblob(100), 1);
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', zeroblob(100), 1)
+0
diff --git a/test/sql_stmt_security_tests/exportdxf11.testcase b/test/sql_stmt_security_tests/exportdxf11.testcase
new file mode 100644
index 0000000..ecfba43
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf11.testcase
@@ -0,0 +1,7 @@
+exportDXF - NULL precision
+:memory: #use in-memory database
+SELECT ExportDXF('.', 'test12345.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10), NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('.', 'test12345.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10), NULL)
+0
diff --git a/test/sql_stmt_security_tests/exportdxf2.testcase b/test/sql_stmt_security_tests/exportdxf2.testcase
new file mode 100644
index 0000000..a84a13f
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf2.testcase
@@ -0,0 +1,7 @@
+exportDXF - null filepath
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', NULL, 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', NULL, 'sql', 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf3.testcase b/test/sql_stmt_security_tests/exportdxf3.testcase
new file mode 100644
index 0000000..5a25c72
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf3.testcase
@@ -0,0 +1,7 @@
+exportDXF - null SQL
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', NULL, 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', NULL, 'layer', 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf4.testcase b/test/sql_stmt_security_tests/exportdxf4.testcase
new file mode 100644
index 0000000..435798d
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf4.testcase
@@ -0,0 +1,7 @@
+exportDXF - null layer
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', NULL, 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', NULL, 'geom', 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf5.testcase b/test/sql_stmt_security_tests/exportdxf5.testcase
new file mode 100644
index 0000000..eb26759
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf5.testcase
@@ -0,0 +1,7 @@
+exportDXF - null geo_column
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', NULL, 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', NULL, 'label', 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf6.testcase b/test/sql_stmt_security_tests/exportdxf6.testcase
new file mode 100644
index 0000000..c9efa03
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf6.testcase
@@ -0,0 +1,7 @@
+exportDXF - null label
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', NULL, 'height', 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', NULL, 'height', 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf7.testcase b/test/sql_stmt_security_tests/exportdxf7.testcase
new file mode 100644
index 0000000..9dfc562
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf7.testcase
@@ -0,0 +1,7 @@
+exportDXF - null height
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', NULL, 'rotation', BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', NULL, 'rotation', BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf8.testcase b/test/sql_stmt_security_tests/exportdxf8.testcase
new file mode 100644
index 0000000..e1cc684
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf8.testcase
@@ -0,0 +1,7 @@
+exportDXF - null rotation
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', NULL, BuildMBR(0, 0, 10, 10));
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', NULL, BuildMBR(0, 0, 10, 10))
+0
diff --git a/test/sql_stmt_security_tests/exportdxf9.testcase b/test/sql_stmt_security_tests/exportdxf9.testcase
new file mode 100644
index 0000000..3124c7d
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportdxf9.testcase
@@ -0,0 +1,7 @@
+exportDXF - null BBOX
+:memory: #use in-memory database
+SELECT ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportDXF('testdir', 'test.dxf', 'sql', 'layer', 'geom', 'label', 'height', 'rotation', NULL)
+0
diff --git a/test/sql_stmt_security_tests/exportgeojson1.testcase b/test/sql_stmt_security_tests/exportgeojson1.testcase
new file mode 100644
index 0000000..6601a16
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson1.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - NULL table
+:memory: #use in-memory database
+SELECT ExportGeoJSON(NULL, 'geom', 'sample.geojson');
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON(NULL, 'geom', 'sample.geojson')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson10.testcase b/test/sql_stmt_security_tests/exportgeojson10.testcase
new file mode 100644
index 0000000..52fa8c3
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson10.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - not existing table #5
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBRwithLongCRS', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBRwithLongCRS', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson11.testcase b/test/sql_stmt_security_tests/exportgeojson11.testcase
new file mode 100644
index 0000000..ab151eb
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson11.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - undefined format
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'crazy', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'crazy', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson2.testcase b/test/sql_stmt_security_tests/exportgeojson2.testcase
new file mode 100644
index 0000000..2823220
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson2.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - NULL geometry-column
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', NULL, 'sample.geojson');
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', NULL, 'sample.geojson')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson3.testcase b/test/sql_stmt_security_tests/exportgeojson3.testcase
new file mode 100644
index 0000000..31335bc
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson3.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - NULL filename
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson4.testcase b/test/sql_stmt_security_tests/exportgeojson4.testcase
new file mode 100644
index 0000000..dcd94ae
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson4.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - NULL format
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson5.testcase b/test/sql_stmt_security_tests/exportgeojson5.testcase
new file mode 100644
index 0000000..93ac4fd
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson5.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - NULL precision
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'none', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'none', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson6.testcase b/test/sql_stmt_security_tests/exportgeojson6.testcase
new file mode 100644
index 0000000..9464f98
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson6.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - not existing table #1
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'withShortCRS', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'withShortCRS', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson7.testcase b/test/sql_stmt_security_tests/exportgeojson7.testcase
new file mode 100644
index 0000000..1a472b7
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson7.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - not existing table #2
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBR', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBR', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson8.testcase b/test/sql_stmt_security_tests/exportgeojson8.testcase
new file mode 100644
index 0000000..05af4d3
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson8.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - not existing table #4
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBRwithShortCRS', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'MBRwithShortCRS', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportgeojson9.testcase b/test/sql_stmt_security_tests/exportgeojson9.testcase
new file mode 100644
index 0000000..9db23e2
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportgeojson9.testcase
@@ -0,0 +1,7 @@
+exportGeoJSON - not existing table #4
+:memory: #use in-memory database
+SELECT ExportGeoJSON('table', 'geom', 'sample.geojson', 'withLongCRS', 6);
+1 # rows (not including the header row)
+1 # columns
+ExportGeoJSON('table', 'geom', 'sample.geojson', 'withLongCRS', 6)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml1.testcase b/test/sql_stmt_security_tests/exportkml1.testcase
new file mode 100644
index 0000000..8c79461
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml1.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL table
+:memory: #use in-memory database
+SELECT ExportKML(NULL, 'geom', 'sample.kml');
+1 # rows (not including the header row)
+1 # columns
+ExportKML(NULL, 'geom', 'sample.kml')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml2.testcase b/test/sql_stmt_security_tests/exportkml2.testcase
new file mode 100644
index 0000000..2a8afa5
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml2.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL geometry-column
+:memory: #use in-memory database
+SELECT ExportKML('table', NULL, 'sample.kml');
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', NULL, 'sample.kml')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml3.testcase b/test/sql_stmt_security_tests/exportkml3.testcase
new file mode 100644
index 0000000..9736894
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml3.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL filename
+:memory: #use in-memory database
+SELECT ExportKML('table', 'geom', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', 'geom', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml4.testcase b/test/sql_stmt_security_tests/exportkml4.testcase
new file mode 100644
index 0000000..b692026
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml4.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL precision
+:memory: #use in-memory database
+SELECT ExportKML('table', 'geom', 'sample.kml', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', 'geom', 'sample.kml', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml5.testcase b/test/sql_stmt_security_tests/exportkml5.testcase
new file mode 100644
index 0000000..a15c464
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml5.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL name_column
+:memory: #use in-memory database
+SELECT ExportKML('table', 'geom', 'sample.kml', 6, NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', 'geom', 'sample.kml', 6, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml6.testcase b/test/sql_stmt_security_tests/exportkml6.testcase
new file mode 100644
index 0000000..37a302c
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml6.testcase
@@ -0,0 +1,7 @@
+exportKML - NULL description_column
+:memory: #use in-memory database
+SELECT ExportKML('table', 'geom', 'sample.kml', 6, 'name', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', 'geom', 'sample.kml', 6, 'name', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportkml7.testcase b/test/sql_stmt_security_tests/exportkml7.testcase
new file mode 100644
index 0000000..68256cd
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportkml7.testcase
@@ -0,0 +1,7 @@
+exportKML - not existing column
+:memory: #use in-memory database
+SELECT ExportKML('table', 'geom', 'sample.kml', 6, 'name', 'description');
+1 # rows (not including the header row)
+1 # columns
+ExportKML('table', 'geom', 'sample.kml', 6, 'name', 'description')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp1.testcase b/test/sql_stmt_security_tests/exportshp1.testcase
new file mode 100644
index 0000000..c24d172
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp1.testcase
@@ -0,0 +1,7 @@
+exportSHP - NULL table
+:memory: #use in-memory database
+SELECT ExportSHP(NULL, 'geom', 'shapefile', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportSHP(NULL, 'geom', 'shapefile', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp2.testcase b/test/sql_stmt_security_tests/exportshp2.testcase
new file mode 100644
index 0000000..2aaf7f2
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp2.testcase
@@ -0,0 +1,7 @@
+exportSHP - NULL geo-column
+:memory: #use in-memory database
+SELECT ExportSHP('test', NULL, 'shapefile', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportSHP('test', NULL, 'shapefile', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp3.testcase b/test/sql_stmt_security_tests/exportshp3.testcase
new file mode 100644
index 0000000..9fa5d87
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp3.testcase
@@ -0,0 +1,7 @@
+exportSHP - NULL filename
+:memory: #use in-memory database
+SELECT ExportSHP('test', 'geom', NULL, 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ExportSHP('test', 'geom', NULL, 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp4.testcase b/test/sql_stmt_security_tests/exportshp4.testcase
new file mode 100644
index 0000000..08406b9
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp4.testcase
@@ -0,0 +1,7 @@
+exportSHP - NULL charset
+:memory: #use in-memory database
+SELECT ExportSHP('test', 'geom', 'shapefile', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportSHP('test', 'geom', 'shapefile', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp5.testcase b/test/sql_stmt_security_tests/exportshp5.testcase
new file mode 100644
index 0000000..7bf5763
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp5.testcase
@@ -0,0 +1,7 @@
+exportSHP - NULL geometry-type
+:memory: #use in-memory database
+SELECT ExportSHP('test', 'geom', 'shapefile', 'UTF-8', NULL);
+1 # rows (not including the header row)
+1 # columns
+ExportSHP('test', 'geom', 'shapefile', 'UTF-8', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/exportshp6.testcase b/test/sql_stmt_security_tests/exportshp6.testcase
new file mode 100644
index 0000000..2a603b6
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportshp6.testcase
@@ -0,0 +1,7 @@
+exportSHP - not existing table
+:memory: #use in-memory database
+SELECT ExportSHP('test', 'geom', 'shapefile', 'UTF-8', 'POINT');
+1 # rows (not including the header row)
+1 # columns
+ExportSHP('test', 'geom', 'shapefile', 'UTF-8', 'POINT')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf1.testcase b/test/sql_stmt_security_tests/importdbf1.testcase
new file mode 100644
index 0000000..f01140e
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf1.testcase
@@ -0,0 +1,7 @@
+importDBF - NULL filename
+:memory: #use in-memory database
+SELECT ImportDBF(NULL, 'table', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ImportDBF(NULL, 'table', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf2.testcase b/test/sql_stmt_security_tests/importdbf2.testcase
new file mode 100644
index 0000000..c174540
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf2.testcase
@@ -0,0 +1,7 @@
+importDBF - NULL table
+:memory: #use in-memory database
+SELECT ImportDBF('test.dbf', NULL, 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('test.dbf', NULL, 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf3.testcase b/test/sql_stmt_security_tests/importdbf3.testcase
new file mode 100644
index 0000000..6d0e5e5
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf3.testcase
@@ -0,0 +1,7 @@
+importDBF - NULL charset
+:memory: #use in-memory database
+SELECT ImportDBF('test.dbf', 'table', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('test.dbf', 'table', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf4.testcase b/test/sql_stmt_security_tests/importdbf4.testcase
new file mode 100644
index 0000000..84f3fe4
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf4.testcase
@@ -0,0 +1,7 @@
+importDBF - NULL pk_column
+:memory: #use in-memory database
+SELECT ImportDBF('test.dbf', 'table', 'UTF-8', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('test.dbf', 'table', 'UTF-8', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf5.testcase b/test/sql_stmt_security_tests/importdbf5.testcase
new file mode 100644
index 0000000..89e5dd6
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf5.testcase
@@ -0,0 +1,7 @@
+importDBF - NULL text_dates
+:memory: #use in-memory database
+SELECT ImportDBF('test.dbf', 'table', 'UTF-8', 'id', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('test.dbf', 'table', 'UTF-8', 'id', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf6.testcase b/test/sql_stmt_security_tests/importdbf6.testcase
new file mode 100644
index 0000000..39a810c
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf6.testcase
@@ -0,0 +1,7 @@
+importDBF - not existing file
+:memory: #use in-memory database
+SELECT ImportDBF('test.dbf', 'table', 'UTF-8', 'id', 1);
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('test.dbf', 'table', 'UTF-8', 'id', 1)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdbf7.testcase b/test/sql_stmt_security_tests/importdbf7.testcase
new file mode 100644
index 0000000..6b12b08
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdbf7.testcase
@@ -0,0 +1,7 @@
+importDBF - existing file
+:memory: #use in-memory database
+SELECT ImportDBF('./shapetest1.dbf', 'dbftable', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ImportDBF('./shapetest1.dbf', 'dbftable', 'UTF-8')
+2
diff --git a/test/sql_stmt_security_tests/importdxf1.testcase b/test/sql_stmt_security_tests/importdxf1.testcase
new file mode 100644
index 0000000..ce763a7
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf1.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL filename
+:memory: #use in-memory database
+SELECT ImportDXF(NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDXF(NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf10.testcase b/test/sql_stmt_security_tests/importdxf10.testcase
new file mode 100644
index 0000000..8ee9db2
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf10.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL layer
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'LINKED', 'prefix', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'LINKED', 'prefix', NULL)
+0
diff --git a/test/sql_stmt_security_tests/importdxf11.testcase b/test/sql_stmt_security_tests/importdxf11.testcase
new file mode 100644
index 0000000..a640cc9
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf11.testcase
@@ -0,0 +1,7 @@
+importDXF - INT layer
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 1);
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 1)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf12.testcase b/test/sql_stmt_security_tests/importdxf12.testcase
new file mode 100644
index 0000000..7b0acc4
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf12.testcase
@@ -0,0 +1,7 @@
+importDXF - Not existing DXF
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer')
+0
diff --git a/test/sql_stmt_security_tests/importdxf13.testcase b/test/sql_stmt_security_tests/importdxf13.testcase
new file mode 100644
index 0000000..3ce1d47
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf13.testcase
@@ -0,0 +1,7 @@
+importDXF - invalid dimensions
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '123D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '123D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf14.testcase b/test/sql_stmt_security_tests/importdxf14.testcase
new file mode 100644
index 0000000..752d579
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf14.testcase
@@ -0,0 +1,7 @@
+importDXF - invalid mode
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'foo', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'foo', 'UNLINKED', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf15.testcase b/test/sql_stmt_security_tests/importdxf15.testcase
new file mode 100644
index 0000000..d72cf28
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf15.testcase
@@ -0,0 +1,7 @@
+importDXF - invalid special rings
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'foo', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'foo', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf16.testcase b/test/sql_stmt_security_tests/importdxf16.testcase
new file mode 100644
index 0000000..297b58a
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf16.testcase
@@ -0,0 +1,7 @@
+importDXF - existing file
+:memory: #use in-memory database
+SELECT ImportDXF('./f06.dxf');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('./f06.dxf')
+1
diff --git a/test/sql_stmt_security_tests/importdxf2.testcase b/test/sql_stmt_security_tests/importdxf2.testcase
new file mode 100644
index 0000000..4ec0755
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf2.testcase
@@ -0,0 +1,7 @@
+importDXF - not existing file
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf')
+0
diff --git a/test/sql_stmt_security_tests/importdxf3.testcase b/test/sql_stmt_security_tests/importdxf3.testcase
new file mode 100644
index 0000000..a35765b
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf3.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL srid
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', NULL, 1, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', NULL, 1, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf4.testcase b/test/sql_stmt_security_tests/importdxf4.testcase
new file mode 100644
index 0000000..112bc59
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf4.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL append
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, NULL, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, NULL, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf5.testcase b/test/sql_stmt_security_tests/importdxf5.testcase
new file mode 100644
index 0000000..d4a9a9d
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf5.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL dimensions
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, NULL, 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, NULL, 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf6.testcase b/test/sql_stmt_security_tests/importdxf6.testcase
new file mode 100644
index 0000000..efbc1b7
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf6.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL mode
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, 'AUTO', NULL, 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, 'AUTO', NULL, 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf7.testcase b/test/sql_stmt_security_tests/importdxf7.testcase
new file mode 100644
index 0000000..f930ea3
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf7.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL special_rings
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, 'AUTO', 'MIXED', NULL, 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, 'AUTO', 'MIXED', NULL, 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxf8.testcase b/test/sql_stmt_security_tests/importdxf8.testcase
new file mode 100644
index 0000000..d67fee7
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf8.testcase
@@ -0,0 +1,7 @@
+importDXF - NULL prefix
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '2D', 'MIXED', 'NONE', NULL, 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '2D', 'MIXED', 'NONE', NULL, 'layer')
+0
diff --git a/test/sql_stmt_security_tests/importdxf9.testcase b/test/sql_stmt_security_tests/importdxf9.testcase
new file mode 100644
index 0000000..86f23b4
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxf9.testcase
@@ -0,0 +1,7 @@
+importDXF - INT prefix
+:memory: #use in-memory database
+SELECT ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'LINKED', 1, 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXF('sample.dxf', 4326, 1, '3D', 'DISTINCT', 'LINKED', 1, 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir1.testcase b/test/sql_stmt_security_tests/importdxfdir1.testcase
new file mode 100644
index 0000000..cc56734
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir1.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL dir
+:memory: #use in-memory database
+SELECT ImportDXFfromDir(NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir(NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir10.testcase b/test/sql_stmt_security_tests/importdxfdir10.testcase
new file mode 100644
index 0000000..ff08449
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir10.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL layer
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('foo', 4326, 1, '3D', 'DISTINCT', 'LINKED', 'prefix', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('foo', 4326, 1, '3D', 'DISTINCT', 'LINKED', 'prefix', NULL)
+0
diff --git a/test/sql_stmt_security_tests/importdxfdir11.testcase b/test/sql_stmt_security_tests/importdxfdir11.testcase
new file mode 100644
index 0000000..d7d69aa
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir11.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - INT layer
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 1);
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 1)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir12.testcase b/test/sql_stmt_security_tests/importdxfdir12.testcase
new file mode 100644
index 0000000..f976092
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir12.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - Not existing Dir
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('foo', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('foo', 4326, 1, '3D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer')
+0
diff --git a/test/sql_stmt_security_tests/importdxfdir13.testcase b/test/sql_stmt_security_tests/importdxfdir13.testcase
new file mode 100644
index 0000000..31d6ed1
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir13.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - invalid dimensions
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, '123D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, '123D', 'DISTINCT', 'UNLINKED', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir14.testcase b/test/sql_stmt_security_tests/importdxfdir14.testcase
new file mode 100644
index 0000000..b7cd438
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir14.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - invalid mode
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, '3D', 'foo', 'UNLINKED', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, '3D', 'foo', 'UNLINKED', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir15.testcase b/test/sql_stmt_security_tests/importdxfdir15.testcase
new file mode 100644
index 0000000..630f8b9
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir15.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - invalid special rings
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'foo', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'foo', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir16.testcase b/test/sql_stmt_security_tests/importdxfdir16.testcase
new file mode 100644
index 0000000..efbf8a8
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir16.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - existing file
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 32632, 1, '3D', 'DISTINCT', 'NONE', 'prefix_', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 32632, 1, '3D', 'DISTINCT', 'NONE', 'prefix_', NULL)
+9
diff --git a/test/sql_stmt_security_tests/importdxfdir2.testcase b/test/sql_stmt_security_tests/importdxfdir2.testcase
new file mode 100644
index 0000000..325d85d
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir2.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - not existing file
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('foo');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('foo')
+0
diff --git a/test/sql_stmt_security_tests/importdxfdir3.testcase b/test/sql_stmt_security_tests/importdxfdir3.testcase
new file mode 100644
index 0000000..1691f32
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir3.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL srid
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', NULL, 1, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', NULL, 1, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir4.testcase b/test/sql_stmt_security_tests/importdxfdir4.testcase
new file mode 100644
index 0000000..80d48cb
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir4.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL append
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, NULL, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, NULL, 'AUTO', 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir5.testcase b/test/sql_stmt_security_tests/importdxfdir5.testcase
new file mode 100644
index 0000000..95a39ec
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir5.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL dimensions
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, NULL, 'MIXED', 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, NULL, 'MIXED', 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir6.testcase b/test/sql_stmt_security_tests/importdxfdir6.testcase
new file mode 100644
index 0000000..a2f1d39
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir6.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL mode
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, 'AUTO', NULL, 'NONE', 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, 'AUTO', NULL, 'NONE', 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir7.testcase b/test/sql_stmt_security_tests/importdxfdir7.testcase
new file mode 100644
index 0000000..bec5249
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir7.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL special_rings
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, 'AUTO', 'MIXED', NULL, 'prefix', 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, 'AUTO', 'MIXED', NULL, 'prefix', 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importdxfdir8.testcase b/test/sql_stmt_security_tests/importdxfdir8.testcase
new file mode 100644
index 0000000..a389688
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir8.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - NULL prefix
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('foo', 4326, 1, '2D', 'MIXED', 'NONE', NULL, 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('foo', 4326, 1, '2D', 'MIXED', 'NONE', NULL, 'layer')
+0
diff --git a/test/sql_stmt_security_tests/importdxfdir9.testcase b/test/sql_stmt_security_tests/importdxfdir9.testcase
new file mode 100644
index 0000000..5b2662a
--- /dev/null
+++ b/test/sql_stmt_security_tests/importdxfdir9.testcase
@@ -0,0 +1,7 @@
+importDXFfromDir - INT prefix
+:memory: #use in-memory database
+SELECT ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'LINKED', 1, 'layer');
+1 # rows (not including the header row)
+1 # columns
+ImportDXFfromDir('.', 4326, 1, '3D', 'DISTINCT', 'LINKED', 1, 'layer')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp1.testcase b/test/sql_stmt_security_tests/importshp1.testcase
new file mode 100644
index 0000000..fd4f4b3
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp1.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL filename
+:memory: #use in-memory database
+SELECT ImportSHP(NULL, 'table', 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ImportSHP(NULL, 'table', 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp10.testcase b/test/sql_stmt_security_tests/importshp10.testcase
new file mode 100644
index 0000000..63eb4a5
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp10.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL compressed
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp11.testcase b/test/sql_stmt_security_tests/importshp11.testcase
new file mode 100644
index 0000000..93e5862
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp11.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL spatial_index
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp12.testcase b/test/sql_stmt_security_tests/importshp12.testcase
new file mode 100644
index 0000000..f609954
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp12.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL text_dates
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp13.testcase b/test/sql_stmt_security_tests/importshp13.testcase
new file mode 100644
index 0000000..57ba7ae
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp13.testcase
@@ -0,0 +1,7 @@
+importSHP - not existing shapefile
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', 1, 1, 1, 1)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp14.testcase b/test/sql_stmt_security_tests/importshp14.testcase
new file mode 100644
index 0000000..4fe313b
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp14.testcase
@@ -0,0 +1,7 @@
+importSHP - existing shapefile
+:memory: #use in-memory database
+SELECT ImportSHP('./shp/merano-3d/roads', 'shptable', 'UTF-8', 32632);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('./shp/merano-3d/roads', 'shptable', 'UTF-8', 32632)
+18
diff --git a/test/sql_stmt_security_tests/importshp2.testcase b/test/sql_stmt_security_tests/importshp2.testcase
new file mode 100644
index 0000000..911803c
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp2.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL table
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', NULL, 'UTF-8');
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', NULL, 'UTF-8')
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp3.testcase b/test/sql_stmt_security_tests/importshp3.testcase
new file mode 100644
index 0000000..f1768c4
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp3.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL charset
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp4.testcase b/test/sql_stmt_security_tests/importshp4.testcase
new file mode 100644
index 0000000..e1a9acc
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp4.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL srid
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp5.testcase b/test/sql_stmt_security_tests/importshp5.testcase
new file mode 100644
index 0000000..7e6bf56
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp5.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL geo-column
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp6.testcase b/test/sql_stmt_security_tests/importshp6.testcase
new file mode 100644
index 0000000..7e6bf56
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp6.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL geo-column
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp7.testcase b/test/sql_stmt_security_tests/importshp7.testcase
new file mode 100644
index 0000000..cf241e7
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp7.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL pk-column
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp8.testcase b/test/sql_stmt_security_tests/importshp8.testcase
new file mode 100644
index 0000000..3b52d48
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp8.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL geometry-tryp
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', NULL)
+(NULL)
diff --git a/test/sql_stmt_security_tests/importshp9.testcase b/test/sql_stmt_security_tests/importshp9.testcase
new file mode 100644
index 0000000..cccec00
--- /dev/null
+++ b/test/sql_stmt_security_tests/importshp9.testcase
@@ -0,0 +1,7 @@
+importSHP - NULL coerce2d
+:memory: #use in-memory database
+SELECT ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportSHP('shapefile', 'table', 'UTF-8', 4326, 'geom', 'id', 'POINT', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/Makefile.am b/test/sql_stmt_tests/Makefile.am
index 7806e31..610f69b 100644
--- a/test/sql_stmt_tests/Makefile.am
+++ b/test/sql_stmt_tests/Makefile.am
@@ -310,8 +310,25 @@ EXTRA_DIST = addpoint10.testcase \
 	checkspatialmetadata1.testcase \
 	checkspatialmetadata2.testcase \
 	checkspatialmetadata3.testcase \
+	checkdupl1.testcase \
+	checkdupl2.testcase \
 	checkspatialmetadata4.testcase \
 	checkspatialmetadata5.testcase \
+	clonetable1.testcase \
+	clonetable2.testcase \
+	clonetable3.testcase \
+	clonetable4.testcase \
+	clonetable5.testcase \
+	clonetable6.testcase \
+	clonetable7.testcase \
+	clonetable8.testcase \
+	clonetable9.testcase \
+	clonetable10.testcase \
+	clonetable11.testcase \
+	clonetable12.testcase \
+	clonetable13.testcase \
+	clonetable14.testcase \
+	clonetable15.testcase \
 	ch_m.testcase \
 	cm_m.testcase \
 	collect10.testcase \
@@ -508,6 +525,17 @@ EXTRA_DIST = addpoint10.testcase \
 	dm_m.testcase \
 	DSC_1467.JPG \
 	DSCN0042.JPG \
+	dropgeo1.testcase \
+	dropgeo2.testcase \
+	dropgeo3.testcase \
+	dropgeo4.testcase \
+	dropgeo5.testcase \
+	elemgeo1.testcase \
+	elemgeo2.testcase \
+	elemgeo3.testcase \
+	elemgeo4.testcase \
+	elemgeo5.testcase \
+	elemgeo6.testcase \
 	emptyfile.txt \
 	endpoint1.testcase \
 	envelope1.testcase \
@@ -1507,6 +1535,8 @@ EXTRA_DIST = addpoint10.testcase \
 	reflectcoords7.testcase \
 	reflectcoords8.testcase \
 	reflectcoords9.testcase \
+	removedupl1.testcase \
+	removedupl2.testcase \
 	removepoint10.testcase \
 	removepoint11.testcase \
 	removepoint12.testcase \
@@ -1634,6 +1664,38 @@ EXTRA_DIST = addpoint10.testcase \
 	setpoint7.testcase \
 	setpoint8.testcase \
 	setpoint9.testcase \
+	setendpoint10.testcase \
+	setendpoint11.testcase \
+	setendpoint12.testcase \
+	setendpoint13.testcase \
+	setendpoint14.testcase \
+	setendpoint15.testcase \
+	setendpoint16.testcase \
+	setendpoint1.testcase \
+	setendpoint2.testcase \
+	setendpoint3.testcase \
+	setendpoint4.testcase \
+	setendpoint5.testcase \
+	setendpoint6.testcase \
+	setendpoint7.testcase \
+	setendpoint8.testcase \
+	setendpoint9.testcase \
+	setstartpoint10.testcase \
+	setstartpoint11.testcase \
+	setstartpoint12.testcase \
+	setstartpoint13.testcase \
+	setstartpoint14.testcase \
+	setstartpoint15.testcase \
+	setstartpoint16.testcase \
+	setstartpoint1.testcase \
+	setstartpoint2.testcase \
+	setstartpoint3.testcase \
+	setstartpoint4.testcase \
+	setstartpoint5.testcase \
+	setstartpoint6.testcase \
+	setstartpoint7.testcase \
+	setstartpoint8.testcase \
+	setstartpoint9.testcase \
 	shiftcoords10.testcase \
 	shiftcoords11.testcase \
 	shiftcoords12.testcase \
diff --git a/test/sql_stmt_tests/Makefile.in b/test/sql_stmt_tests/Makefile.in
index 226b566..411e960 100644
--- a/test/sql_stmt_tests/Makefile.in
+++ b/test/sql_stmt_tests/Makefile.in
@@ -551,8 +551,25 @@ EXTRA_DIST = addpoint10.testcase \
 	checkspatialmetadata1.testcase \
 	checkspatialmetadata2.testcase \
 	checkspatialmetadata3.testcase \
+	checkdupl1.testcase \
+	checkdupl2.testcase \
 	checkspatialmetadata4.testcase \
 	checkspatialmetadata5.testcase \
+	clonetable1.testcase \
+	clonetable2.testcase \
+	clonetable3.testcase \
+	clonetable4.testcase \
+	clonetable5.testcase \
+	clonetable6.testcase \
+	clonetable7.testcase \
+	clonetable8.testcase \
+	clonetable9.testcase \
+	clonetable10.testcase \
+	clonetable11.testcase \
+	clonetable12.testcase \
+	clonetable13.testcase \
+	clonetable14.testcase \
+	clonetable15.testcase \
 	ch_m.testcase \
 	cm_m.testcase \
 	collect10.testcase \
@@ -749,6 +766,17 @@ EXTRA_DIST = addpoint10.testcase \
 	dm_m.testcase \
 	DSC_1467.JPG \
 	DSCN0042.JPG \
+	dropgeo1.testcase \
+	dropgeo2.testcase \
+	dropgeo3.testcase \
+	dropgeo4.testcase \
+	dropgeo5.testcase \
+	elemgeo1.testcase \
+	elemgeo2.testcase \
+	elemgeo3.testcase \
+	elemgeo4.testcase \
+	elemgeo5.testcase \
+	elemgeo6.testcase \
 	emptyfile.txt \
 	endpoint1.testcase \
 	envelope1.testcase \
@@ -1748,6 +1776,8 @@ EXTRA_DIST = addpoint10.testcase \
 	reflectcoords7.testcase \
 	reflectcoords8.testcase \
 	reflectcoords9.testcase \
+	removedupl1.testcase \
+	removedupl2.testcase \
 	removepoint10.testcase \
 	removepoint11.testcase \
 	removepoint12.testcase \
@@ -1875,6 +1905,38 @@ EXTRA_DIST = addpoint10.testcase \
 	setpoint7.testcase \
 	setpoint8.testcase \
 	setpoint9.testcase \
+	setendpoint10.testcase \
+	setendpoint11.testcase \
+	setendpoint12.testcase \
+	setendpoint13.testcase \
+	setendpoint14.testcase \
+	setendpoint15.testcase \
+	setendpoint16.testcase \
+	setendpoint1.testcase \
+	setendpoint2.testcase \
+	setendpoint3.testcase \
+	setendpoint4.testcase \
+	setendpoint5.testcase \
+	setendpoint6.testcase \
+	setendpoint7.testcase \
+	setendpoint8.testcase \
+	setendpoint9.testcase \
+	setstartpoint10.testcase \
+	setstartpoint11.testcase \
+	setstartpoint12.testcase \
+	setstartpoint13.testcase \
+	setstartpoint14.testcase \
+	setstartpoint15.testcase \
+	setstartpoint16.testcase \
+	setstartpoint1.testcase \
+	setstartpoint2.testcase \
+	setstartpoint3.testcase \
+	setstartpoint4.testcase \
+	setstartpoint5.testcase \
+	setstartpoint6.testcase \
+	setstartpoint7.testcase \
+	setstartpoint8.testcase \
+	setstartpoint9.testcase \
 	shiftcoords10.testcase \
 	shiftcoords11.testcase \
 	shiftcoords12.testcase \
diff --git a/test/sql_stmt_tests/checkdupl1.testcase b/test/sql_stmt_tests/checkdupl1.testcase
new file mode 100644
index 0000000..d71b7b9
--- /dev/null
+++ b/test/sql_stmt_tests/checkdupl1.testcase
@@ -0,0 +1,7 @@
+CheckDuplicateRows() - NULL table
+:memory: #use in-memory database
+SELECT CheckDuplicateRows(NULL);
+1 # rows (not including the header row)
+1 # columns
+CheckDuplicateRows(NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/checkdupl2.testcase b/test/sql_stmt_tests/checkdupl2.testcase
new file mode 100644
index 0000000..2f5d47b
--- /dev/null
+++ b/test/sql_stmt_tests/checkdupl2.testcase
@@ -0,0 +1,7 @@
+CheckDuplicateRows() - not existing table
+:memory: #use in-memory database
+SELECT CheckDuplicateRows('table');
+1 # rows (not including the header row)
+1 # columns
+CheckDuplicateRows('table')
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable1.testcase b/test/sql_stmt_tests/clonetable1.testcase
new file mode 100644
index 0000000..9b81949
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable1.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL db-prefix
+:memory: #use in-memory database
+SELECT CloneTable(NULL, 'in_table', 'out_table', 1)
+1 # rows (not including the header row)
+1 # columns
+CloneTable(NULL, 'in_table', 'out_table', 1)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable10.testcase b/test/sql_stmt_tests/clonetable10.testcase
new file mode 100644
index 0000000..e610b98
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable10.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #6
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable11.testcase b/test/sql_stmt_tests/clonetable11.testcase
new file mode 100644
index 0000000..2623e15
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable11.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #7
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable12.testcase b/test/sql_stmt_tests/clonetable12.testcase
new file mode 100644
index 0000000..729bdc3
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable12.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #8
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable13.testcase b/test/sql_stmt_tests/clonetable13.testcase
new file mode 100644
index 0000000..f0bae74
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable13.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #9
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable14.testcase b/test/sql_stmt_tests/clonetable14.testcase
new file mode 100644
index 0000000..f190a5b
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable14.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #10
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', 'opt9', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', 'opt9', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable15.testcase b/test/sql_stmt_tests/clonetable15.testcase
new file mode 100644
index 0000000..34f7df6
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable15.testcase
@@ -0,0 +1,7 @@
+CloneTable() - not existing input
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', 'opt9', 'opt10')
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6', 'opt7', 'opt8', 'opt9', 'opt10')
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable2.testcase b/test/sql_stmt_tests/clonetable2.testcase
new file mode 100644
index 0000000..8165cde
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable2.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL input-table
+:memory: #use in-memory database
+SELECT CloneTable('prefix', NULL, 'out_table', 1)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', NULL, 'out_table', 1)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable3.testcase b/test/sql_stmt_tests/clonetable3.testcase
new file mode 100644
index 0000000..b787f6c
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable3.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL output-table
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', NULL, 1)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', NULL, 1)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable4.testcase b/test/sql_stmt_tests/clonetable4.testcase
new file mode 100644
index 0000000..fb3457d
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable4.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL transaction
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable5.testcase b/test/sql_stmt_tests/clonetable5.testcase
new file mode 100644
index 0000000..434f940
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable5.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #1
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable6.testcase b/test/sql_stmt_tests/clonetable6.testcase
new file mode 100644
index 0000000..7297265
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable6.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #2
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable7.testcase b/test/sql_stmt_tests/clonetable7.testcase
new file mode 100644
index 0000000..a72f92b
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable7.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #3
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable8.testcase b/test/sql_stmt_tests/clonetable8.testcase
new file mode 100644
index 0000000..f8c197a
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable8.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #4
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', 'opt3', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', 'opt3', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/clonetable9.testcase b/test/sql_stmt_tests/clonetable9.testcase
new file mode 100644
index 0000000..423e906
--- /dev/null
+++ b/test/sql_stmt_tests/clonetable9.testcase
@@ -0,0 +1,7 @@
+CloneTable() - NULL option #5
+:memory: #use in-memory database
+SELECT CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', 'opt3', 'opt4', NULL)
+1 # rows (not including the header row)
+1 # columns
+CloneTable('prefix', 'in_table', 'out_table', 1, 'option-1', 'option-2', 'opt3', 'opt4', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/dropgeo1.testcase b/test/sql_stmt_tests/dropgeo1.testcase
new file mode 100644
index 0000000..8ff3a0a
--- /dev/null
+++ b/test/sql_stmt_tests/dropgeo1.testcase
@@ -0,0 +1,7 @@
+DropGeoTable - NULL table
+:memory: #use in-memory database
+SELECT DropGeoTable(NULL);
+1 # rows (not including the header row)
+1 # columns
+DropGeoTable(NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/dropgeo2.testcase b/test/sql_stmt_tests/dropgeo2.testcase
new file mode 100644
index 0000000..e8707eb
--- /dev/null
+++ b/test/sql_stmt_tests/dropgeo2.testcase
@@ -0,0 +1,7 @@
+DropGeoTable - NULL prefix
+:memory: #use in-memory database
+SELECT DropGeoTable(NULL, 'table');
+1 # rows (not including the header row)
+1 # columns
+DropGeoTable(NULL, 'table')
+(NULL)
diff --git a/test/sql_stmt_tests/dropgeo3.testcase b/test/sql_stmt_tests/dropgeo3.testcase
new file mode 100644
index 0000000..ace02c9
--- /dev/null
+++ b/test/sql_stmt_tests/dropgeo3.testcase
@@ -0,0 +1,7 @@
+DropGeoTable - prefix, NULL table
+:memory: #use in-memory database
+SELECT DropGeoTable('prefix', NULL);
+1 # rows (not including the header row)
+1 # columns
+DropGeoTable('prefix', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/dropgeo4.testcase b/test/sql_stmt_tests/dropgeo4.testcase
new file mode 100644
index 0000000..5d7c5d0
--- /dev/null
+++ b/test/sql_stmt_tests/dropgeo4.testcase
@@ -0,0 +1,7 @@
+DropGeoTable - prefix, table (not existing)
+:memory: #use in-memory database
+SELECT DropGeoTable('prefix', 'table');
+1 # rows (not including the header row)
+1 # columns
+DropGeoTable('prefix', 'table')
+0
diff --git a/test/sql_stmt_tests/dropgeo5.testcase b/test/sql_stmt_tests/dropgeo5.testcase
new file mode 100644
index 0000000..8e26a77
--- /dev/null
+++ b/test/sql_stmt_tests/dropgeo5.testcase
@@ -0,0 +1,7 @@
+DropGeoTable - table (not existing)
+:memory: #use in-memory database
+SELECT DropGeoTable('table');
+1 # rows (not including the header row)
+1 # columns
+DropGeoTable('table')
+0
diff --git a/test/sql_stmt_tests/elemgeo1.testcase b/test/sql_stmt_tests/elemgeo1.testcase
new file mode 100644
index 0000000..9340021
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo1.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - NULL input_table
+:memory: #use in-memory database
+SELECT ElementaryGeometries(NULL, 'geom', 'out_table', 'id', 'old_id');
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries(NULL, 'geom', 'out_table', 'id', 'old_id')
+(NULL)
diff --git a/test/sql_stmt_tests/elemgeo2.testcase b/test/sql_stmt_tests/elemgeo2.testcase
new file mode 100644
index 0000000..4fd1147
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo2.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - NULL geometry-column
+:memory: #use in-memory database
+SELECT ElementaryGeometries('in_table', NULL, 'out_table', 'id', 'old_id');
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries('in_table', NULL, 'out_table', 'id', 'old_id')
+(NULL)
diff --git a/test/sql_stmt_tests/elemgeo3.testcase b/test/sql_stmt_tests/elemgeo3.testcase
new file mode 100644
index 0000000..500f3fc
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo3.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - NULL output-table
+:memory: #use in-memory database
+SELECT ElementaryGeometries('in_table', 'geom', NULL, 'id', 'old_id');
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries('in_table', 'geom', NULL, 'id', 'old_id')
+(NULL)
diff --git a/test/sql_stmt_tests/elemgeo4.testcase b/test/sql_stmt_tests/elemgeo4.testcase
new file mode 100644
index 0000000..0494e41
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo4.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - NULL primary-key
+:memory: #use in-memory database
+SELECT ElementaryGeometries('in_table', 'geom', 'out_table', NULL, 'old_id');
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries('in_table', 'geom', 'out_table', NULL, 'old_id')
+(NULL)
diff --git a/test/sql_stmt_tests/elemgeo5.testcase b/test/sql_stmt_tests/elemgeo5.testcase
new file mode 100644
index 0000000..f12b172
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo5.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - NULL multi-id
+:memory: #use in-memory database
+SELECT ElementaryGeometries('in_table', 'geom', 'out_table', 'id', NULL);
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries('in_table', 'geom', 'out_table', 'id', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/elemgeo6.testcase b/test/sql_stmt_tests/elemgeo6.testcase
new file mode 100644
index 0000000..7888f57
--- /dev/null
+++ b/test/sql_stmt_tests/elemgeo6.testcase
@@ -0,0 +1,7 @@
+ElementaryGeometries() - not existing table
+:memory: #use in-memory database
+SELECT ElementaryGeometries('in_table', 'geom', 'out_table', 'id', 'old_id');
+1 # rows (not including the header row)
+1 # columns
+ElementaryGeometries('in_table', 'geom', 'out_table', 'id', 'old_id')
+(NULL)
diff --git a/test/sql_stmt_tests/removedupl1.testcase b/test/sql_stmt_tests/removedupl1.testcase
new file mode 100644
index 0000000..31ef902
--- /dev/null
+++ b/test/sql_stmt_tests/removedupl1.testcase
@@ -0,0 +1,7 @@
+RemoveDuplicateRows() - NULL table
+:memory: #use in-memory database
+SELECT RemoveDuplicateRows(NULL);
+1 # rows (not including the header row)
+1 # columns
+RemoveDuplicateRows(NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/removedupl2.testcase b/test/sql_stmt_tests/removedupl2.testcase
new file mode 100644
index 0000000..8ef2aa7
--- /dev/null
+++ b/test/sql_stmt_tests/removedupl2.testcase
@@ -0,0 +1,7 @@
+RemoveDuplicateRows() - not existing table
+:memory: #use in-memory database
+SELECT RemoveDuplicateRows('table');
+1 # rows (not including the header row)
+1 # columns
+RemoveDuplicateRows('table')
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint1.testcase b/test/sql_stmt_tests/setendpoint1.testcase
new file mode 100644
index 0000000..d0cd3c8
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint1.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - NULL line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(NULL, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(NULL, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint10.testcase b/test/sql_stmt_tests/setendpoint10.testcase
new file mode 100644
index 0000000..fb8755f
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint10.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - BLOB Point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), zeroblob(4))
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), zeroblob(4))
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint11.testcase b/test/sql_stmt_tests/setendpoint11.testcase
new file mode 100644
index 0000000..982b3b6
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint11.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - not a line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('POLYGON((10 10, 11 10, 11 11, 10 11, 10 10))'), MakePoint(2, 0))
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('POLYGON((10 10, 11 10, 11 11, 10 11, 10 10))'), MakePoint(2, 0))
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint12.testcase b/test/sql_stmt_tests/setendpoint12.testcase
new file mode 100644
index 0000000..323d202
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint12.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - not a point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), GeomFromText('MULTILINESTRING(10 10, 11 10), (1 1, 2 2))'))
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), GeomFromText('MULTILINESTRING(10 10, 11 10), (1 1, 2 2))'))
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint13.testcase b/test/sql_stmt_tests/setendpoint13.testcase
new file mode 100644
index 0000000..884e289
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint13.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - XY
+:memory: #use in-memory database
+SELECT AsText(SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), MakePoint(2, 3)))
+LINESTRING(0 0, 1 0, 2 3)
diff --git a/test/sql_stmt_tests/setendpoint14.testcase b/test/sql_stmt_tests/setendpoint14.testcase
new file mode 100644
index 0000000..0e54217
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint14.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - Z
+:memory: #use in-memory database
+SELECT AsText(SetEndPoint(GeomFromText('LINESTRINGZ(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetEndPoint(GeomFromText('LINESTRINGZ(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+LINESTRING Z(0 0 1, 1 0 2, 2 3 0)
diff --git a/test/sql_stmt_tests/setendpoint15.testcase b/test/sql_stmt_tests/setendpoint15.testcase
new file mode 100644
index 0000000..a71f66c
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint15.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - M
+:memory: #use in-memory database
+SELECT AsText(SetEndPoint(GeomFromText('LINESTRINGM(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetEndPoint(GeomFromText('LINESTRINGM(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+LINESTRING M(0 0 1, 1 0 2, 2 3 0)
diff --git a/test/sql_stmt_tests/setendpoint16.testcase b/test/sql_stmt_tests/setendpoint16.testcase
new file mode 100644
index 0000000..3777881
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint16.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - ZM
+:memory: #use in-memory database
+SELECT AsText(SetEndPoint(GeomFromText('LINESTRINGZM(0 0 1 2, 1 0 2 3, 1 1 3 4)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetEndPoint(GeomFromText('LINESTRINGZM(0 0 1 2, 1 0 2 3, 1 1 3 4)'), MakePoint(2, 3)))
+LINESTRING ZM(0 0 1 2, 1 0 2 3, 2 3 0 0)
diff --git a/test/sql_stmt_tests/setendpoint2.testcase b/test/sql_stmt_tests/setendpoint2.testcase
new file mode 100644
index 0000000..c7fc556
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint2.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - INTEGER line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(1, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint3.testcase b/test/sql_stmt_tests/setendpoint3.testcase
new file mode 100644
index 0000000..c997b01
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint3.testcase
@@ -0,0 +1,7 @@
+ST_SetEndtPoint() - DOUBLE line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(1.5, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(1.5, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint4.testcase b/test/sql_stmt_tests/setendpoint4.testcase
new file mode 100644
index 0000000..a6c2521
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint4.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - TEXT line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint('alpha', NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint('alpha', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint5.testcase b/test/sql_stmt_tests/setendpoint5.testcase
new file mode 100644
index 0000000..2c0beae
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint5.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - BLOB line
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(zeroblob(4), NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(zeroblob(4), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint6.testcase b/test/sql_stmt_tests/setendpoint6.testcase
new file mode 100644
index 0000000..c8f8c51
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint6.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - NULL Point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint7.testcase b/test/sql_stmt_tests/setendpoint7.testcase
new file mode 100644
index 0000000..6cb6cf6
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint7.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - INTEGER Point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint8.testcase b/test/sql_stmt_tests/setendpoint8.testcase
new file mode 100644
index 0000000..a188ef3
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint8.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - DOUBLE Point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1.5)
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1.5)
+(NULL)
diff --git a/test/sql_stmt_tests/setendpoint9.testcase b/test/sql_stmt_tests/setendpoint9.testcase
new file mode 100644
index 0000000..8deecf1
--- /dev/null
+++ b/test/sql_stmt_tests/setendpoint9.testcase
@@ -0,0 +1,7 @@
+ST_SetEndPoint() - TEXT Point
+:memory: #use in-memory database
+SELECT ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 'alpha')
+1 # rows (not including the header row)
+1 # columns
+ST_SetEndPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 'alpha')
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint1.testcase b/test/sql_stmt_tests/setstartpoint1.testcase
new file mode 100644
index 0000000..380706d
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint1.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - NULL line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(NULL, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(NULL, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint10.testcase b/test/sql_stmt_tests/setstartpoint10.testcase
new file mode 100644
index 0000000..ce3363b
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint10.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - BLOB Point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), zeroblob(4))
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), zeroblob(4))
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint11.testcase b/test/sql_stmt_tests/setstartpoint11.testcase
new file mode 100644
index 0000000..9f54748
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint11.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - not a line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('POLYGON((10 10, 11 10, 11 11, 10 11, 10 10))'), MakePoint(2, 0))
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('POLYGON((10 10, 11 10, 11 11, 10 11, 10 10))'), MakePoint(2, 0))
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint12.testcase b/test/sql_stmt_tests/setstartpoint12.testcase
new file mode 100644
index 0000000..d55c42d
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint12.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - not a point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), GeomFromText('MULTILINESTRING(10 10, 11 10), (1 1, 2 2))'))
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), GeomFromText('MULTILINESTRING(10 10, 11 10), (1 1, 2 2))'))
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint13.testcase b/test/sql_stmt_tests/setstartpoint13.testcase
new file mode 100644
index 0000000..10f5c34
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint13.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - XY
+:memory: #use in-memory database
+SELECT AsText(SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), MakePoint(2, 3)))
+LINESTRING(2 3, 1 0, 1 1)
diff --git a/test/sql_stmt_tests/setstartpoint14.testcase b/test/sql_stmt_tests/setstartpoint14.testcase
new file mode 100644
index 0000000..8dcdcec
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint14.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - Z
+:memory: #use in-memory database
+SELECT AsText(SetStartPoint(GeomFromText('LINESTRINGZ(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetStartPoint(GeomFromText('LINESTRINGZ(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+LINESTRING Z(2 3 0, 1 0 2, 1 1 3)
diff --git a/test/sql_stmt_tests/setstartpoint15.testcase b/test/sql_stmt_tests/setstartpoint15.testcase
new file mode 100644
index 0000000..c2300c9
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint15.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - M
+:memory: #use in-memory database
+SELECT AsText(SetStartPoint(GeomFromText('LINESTRINGM(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetStartPoint(GeomFromText('LINESTRINGM(0 0 1, 1 0 2, 1 1 3)'), MakePoint(2, 3)))
+LINESTRING M(2 3 0, 1 0 2, 1 1 3)
diff --git a/test/sql_stmt_tests/setstartpoint16.testcase b/test/sql_stmt_tests/setstartpoint16.testcase
new file mode 100644
index 0000000..b1cba09
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint16.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - ZM
+:memory: #use in-memory database
+SELECT AsText(SetStartPoint(GeomFromText('LINESTRINGZM(0 0 1 2, 1 0 2 3, 1 1 3 4)'), MakePoint(2, 3)))
+1 # rows (not including the header row)
+1 # columns
+AsText(SetStartPoint(GeomFromText('LINESTRINGZM(0 0 1 2, 1 0 2 3, 1 1 3 4)'), MakePoint(2, 3)))
+LINESTRING ZM(2 3 0 0, 1 0 2 3, 1 1 3 4)
diff --git a/test/sql_stmt_tests/setstartpoint2.testcase b/test/sql_stmt_tests/setstartpoint2.testcase
new file mode 100644
index 0000000..8c67237
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint2.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - INTEGER line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(1, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint3.testcase b/test/sql_stmt_tests/setstartpoint3.testcase
new file mode 100644
index 0000000..3adee94
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint3.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - DOUBLE line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(1.5, NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(1.5, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint4.testcase b/test/sql_stmt_tests/setstartpoint4.testcase
new file mode 100644
index 0000000..8d7c061
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint4.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - TEXT line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint('alpha', NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint('alpha', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint5.testcase b/test/sql_stmt_tests/setstartpoint5.testcase
new file mode 100644
index 0000000..5df2c17
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint5.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - BLOB line
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(zeroblob(4), NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(zeroblob(4), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint6.testcase b/test/sql_stmt_tests/setstartpoint6.testcase
new file mode 100644
index 0000000..4c64475
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint6.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - NULL Point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), NULL)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint7.testcase b/test/sql_stmt_tests/setstartpoint7.testcase
new file mode 100644
index 0000000..56d0ae9
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint7.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - INTEGER Point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint8.testcase b/test/sql_stmt_tests/setstartpoint8.testcase
new file mode 100644
index 0000000..d39eb51
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint8.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - DOUBLE Point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1.5)
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 1.5)
+(NULL)
diff --git a/test/sql_stmt_tests/setstartpoint9.testcase b/test/sql_stmt_tests/setstartpoint9.testcase
new file mode 100644
index 0000000..28ad390
--- /dev/null
+++ b/test/sql_stmt_tests/setstartpoint9.testcase
@@ -0,0 +1,7 @@
+ST_SetStartPoint() - TEXT Point
+:memory: #use in-memory database
+SELECT ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 'alpha')
+1 # rows (not including the header row)
+1 # columns
+ST_SetStartPoint(GeomFromText('LINESTRING(0 0, 1 0, 1 1)'), 'alpha')
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/Makefile.am b/test/sql_stmt_xmlsec_tests/Makefile.am
index a889471..c334773 100644
--- a/test/sql_stmt_xmlsec_tests/Makefile.am
+++ b/test/sql_stmt_xmlsec_tests/Makefile.am
@@ -20,4 +20,13 @@ EXTRA_DIST = loadxml1.testcase \
 	storexml6.testcase \
 	storexml7.testcase \
 	storexml8.testcase \
-	storexml9.testcase 
+	storexml9.testcase \
+	importwfs1.testcase \
+	importwfs2.testcase \
+	importwfs3.testcase \
+	importwfs4.testcase \
+	importwfs5.testcase \
+	importwfs6.testcase \
+	importwfs7.testcase \
+	importwfs8.testcase \
+	importwfs9.testcase
diff --git a/test/sql_stmt_xmlsec_tests/Makefile.in b/test/sql_stmt_xmlsec_tests/Makefile.in
index a31c487..38e6d7e 100644
--- a/test/sql_stmt_xmlsec_tests/Makefile.in
+++ b/test/sql_stmt_xmlsec_tests/Makefile.in
@@ -261,7 +261,16 @@ EXTRA_DIST = loadxml1.testcase \
 	storexml6.testcase \
 	storexml7.testcase \
 	storexml8.testcase \
-	storexml9.testcase 
+	storexml9.testcase \
+	importwfs1.testcase \
+	importwfs2.testcase \
+	importwfs3.testcase \
+	importwfs4.testcase \
+	importwfs5.testcase \
+	importwfs6.testcase \
+	importwfs7.testcase \
+	importwfs8.testcase \
+	importwfs9.testcase
 
 all: all-am
 
diff --git a/test/sql_stmt_xmlsec_tests/importwfs1.testcase b/test/sql_stmt_xmlsec_tests/importwfs1.testcase
new file mode 100644
index 0000000..bb26eb5
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs1.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL input
+:memory: #use in-memory database
+SELECT ImportWFS(NULL, 'layer', 'table');
+1 # rows (not including the header row)
+1 # columns
+ImportWFS(NULL, 'layer', 'table')
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs2.testcase b/test/sql_stmt_xmlsec_tests/importwfs2.testcase
new file mode 100644
index 0000000..4ffebc8
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs2.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL layer
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', NULL, 'table');
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', NULL, 'table')
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs3.testcase b/test/sql_stmt_xmlsec_tests/importwfs3.testcase
new file mode 100644
index 0000000..6923d51
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs3.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL table
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', NULL)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs4.testcase b/test/sql_stmt_xmlsec_tests/importwfs4.testcase
new file mode 100644
index 0000000..6e02dc2
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs4.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL pk_column
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', 'table', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', 'table', NULL)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs5.testcase b/test/sql_stmt_xmlsec_tests/importwfs5.testcase
new file mode 100644
index 0000000..65a0640
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs5.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL swap_axes
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', 'table', 'id', NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', 'table', 'id', NULL)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs6.testcase b/test/sql_stmt_xmlsec_tests/importwfs6.testcase
new file mode 100644
index 0000000..4ee6e6a
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs6.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL page_size
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, NULL)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs7.testcase b/test/sql_stmt_xmlsec_tests/importwfs7.testcase
new file mode 100644
index 0000000..58e7c70
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs7.testcase
@@ -0,0 +1,7 @@
+ImportWFS - NULL spatial_index
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, 100, NULL);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, 100, NULL)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs8.testcase b/test/sql_stmt_xmlsec_tests/importwfs8.testcase
new file mode 100644
index 0000000..83a3206
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs8.testcase
@@ -0,0 +1,7 @@
+ImportWFS - not existing input
+:memory: #use in-memory database
+SELECT ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, 100, 1);
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('sample.wfs', 'layer', 'table', 'id', 0, 100, 1)
+(NULL)
diff --git a/test/sql_stmt_xmlsec_tests/importwfs9.testcase b/test/sql_stmt_xmlsec_tests/importwfs9.testcase
new file mode 100644
index 0000000..43848ea
--- /dev/null
+++ b/test/sql_stmt_xmlsec_tests/importwfs9.testcase
@@ -0,0 +1,7 @@
+ImportWFS - not existing input
+:memory: #use in-memory database
+SELECT ImportWFS('./test.wfs', 'p02', 'wfstable');
+1 # rows (not including the header row)
+1 # columns
+ImportWFS('./test.wfs', 'p02', 'wfstable')
+3

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/spatialite.git



More information about the Pkg-grass-devel mailing list